RainX_69

NUMBER OF LONGEST INCREASING SUBSEQ. SEGMENT TREE HARD

Feb 12th, 2023 (edited)
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.21 KB | Source Code | 0 0
  1. https://leetcode.com/problems/number-of-longest-increasing-subsequence/
  2.  
  3.  
  4. Given an integer array nums, return the number of longest increasing subsequences.
  5.  
  6. Notice that the sequence has to be strictly increasing.
  7.  
  8.  
  9.  
  10. Example 1:
  11.  
  12. Input: nums = [1,3,5,4,7]
  13. Output: 2
  14. Explanation: The two longest increasing subsequences are [1, 3, 4, 7] and [1, 3, 5, 7].
  15. Example 2:
  16.  
  17. Input: nums = [2,2,2,2,2]
  18. Output: 5
  19. Explanation: The length of the longest increasing subsequence is 1, and there are 5 increasing subsequences of length 1, so output 5.
  20.  
  21.  
  22. Constraints:
  23.  
  24. 1 <= nums.length <= 2000
  25. -10^6 <= nums[i] <= 10^6
  26.  
  27. --------------------------------------------------------------------------------------------------------------------------------------
  28. DYNAMIC PROGRAMMING O(N * N)
  29.  
  30. class Solution {
  31. public:
  32.     int findNumberOfLIS(vector<int>& nums){
  33.         int n=nums.size();
  34.         vector<int> dp(n,1);        
  35.         vector<int> count(n,1);
  36.         for(int end=1;end<n;end++){
  37.             for(int start=0;start<end;start++){
  38.                 if(nums[end]>nums[start]){
  39.                     if(dp[start]+1>dp[end]){
  40.                         dp[end]=1+dp[start];
  41.                         count[end]=count[start];
  42.                     }
  43.                     else if(dp[start]+1==dp[end]){
  44.                         count[end]+=count[start];
  45.                     }
  46.                 }
  47.             }
  48.         }
  49.         int res=0;
  50.         int LIS=*max_element(dp.begin(),dp.end());
  51.         for(int i=0;i<dp.size();i++){
  52.             if(dp[i]==LIS){
  53.                 res+=count[i];
  54.             }
  55.         }
  56.         return res;
  57.     }
  58. };
  59.  
  60. ---------------------------------------------------------------------
  61.  
  62. Segment Tree
  63.  
  64. class Solution {
  65. private:
  66.     vector<pair<int,int>> tree; // pair<int,int> = length,ways
  67. public:
  68.     pair<int,int> chooseBest(pair<int,int> &left, pair<int,int> &right){
  69.         pair<int,int> res;
  70.    
  71.         int mxLen_LFT=left.first;
  72.         int ways_LFT=left.second;
  73.  
  74.         int mxLen_RHT=right.first;
  75.         int ways_RHT=right.second;
  76.  
  77.         if(mxLen_LFT > mxLen_RHT){
  78.             res={mxLen_LFT , ways_LFT};
  79.         }
  80.         else if(mxLen_LFT < mxLen_RHT){
  81.             res={mxLen_RHT , ways_RHT};
  82.         }
  83.         else{
  84.             res.first=mxLen_LFT;
  85.             res.second=ways_LFT+ways_RHT;
  86.         }
  87.         return res;
  88.     }
  89.  
  90.     void update(int start, int end, int parent, int index, int mxLength, int ways){
  91.         if(start==end){
  92.             if(tree[parent].first==mxLength){ // if same maxlength is achieved again, add ways
  93.                 tree[parent].second+=ways;
  94.             }
  95.             else{  // if achieved more length, update length and ways
  96.                 tree[parent]={mxLength,ways};
  97.             }
  98.             return;
  99.         }
  100.         int mid=(start+end)/2;
  101.         if(index<=mid){
  102.             update(start,mid,2*parent+1,index,mxLength,ways);
  103.         }
  104.         else{
  105.             update(mid+1,end,2*parent+2,index,mxLength,ways);
  106.         }
  107.         tree[parent]=chooseBest(tree[2*parent+1],tree[2*parent+2]);
  108.     }
  109.  
  110.     pair<int,int> maxLen(int start, int end, int l, int r, int parent){
  111.         if(start>r || end<l){
  112.             return {0,0};
  113.         }
  114.         if(start>=l && end<=r){
  115.             return tree[parent];
  116.         }
  117.         int mid=(start+end)/2;
  118.         pair<int,int> left=maxLen(start,mid,l,r,2*parent+1);
  119.         pair<int,int> right=maxLen(mid+1,end,l,r,2*parent+2);
  120.         return chooseBest(left,right);
  121.     }
  122.  
  123.     int findNumberOfLIS(vector<int>& nums) {
  124.         vector<pair<int,int>> new_nums;
  125.         for(int i=0;i<nums.size();i++){
  126.             new_nums.push_back({nums[i],i});
  127.         }
  128.    
  129.         sort(new_nums.begin(),new_nums.end());
  130.    
  131.         unordered_map<int,int> rank;
  132.         int mx=0;
  133.         for(int i=0;i<nums.size();i++){
  134.             if(rank.find(new_nums[i].first)==rank.end()){
  135.                 nums[new_nums[i].second]=mx;
  136.                 rank[new_nums[i].first]=mx;
  137.                 mx++;
  138.             }
  139.             else{
  140.                 nums[new_nums[i].second]=rank[new_nums[i].first];
  141.             }
  142.         }
  143.    
  144.         /*
  145.             cout<<"Your new array -> ";
  146.             for(auto c: nums){
  147.                 cout<<c<<" ";
  148.             }
  149.             cout<<endl<<endl;
  150.        */
  151.  
  152.         tree.resize(4*mx+5);
  153.  
  154.         for(int i=0;i<nums.size();i++){
  155.         /* As each element can be a subseq in itself with len=1 and way=1 to form itself*/
  156.             int mxLen=1;  // mxLen- maximum length achieved for this index
  157.             int ways=1;  // ways- number of ways to achieve mxLen at this index
  158.      
  159.             if(nums[i]>0){
  160.                 pair<int,int> info=maxLen(0,mx,0,nums[i]-1,0);
  161.                 if(info.first+1>mxLen){
  162.                     mxLen=info.first+1;
  163.                     ways=info.second;
  164.                 }
  165.             }
  166.        
  167.             /*
  168.             cout<<"largest increasing length ending at index- "<<i<<" is "<<mxLen<<endl;
  169.             cout<<"Number of ways, incs subsq. of len= "<<mxLen<<" ending at index "<<i<<" is "<<ways<<endl<<endl;    
  170.             */
  171.        
  172.             update(0,mx,0,nums[i],mxLen,ways);
  173.         }
  174.         return tree[0].second;    
  175.     }
  176. };
Advertisement
Add Comment
Please, Sign In to add comment