The "number of longest increasing subsequences" of the dynamic programming series

673. The number of longest increasing subsequences

Given an 未排序integer array, find the longest increasing subsequence 个数.

Example 1:

输入: [1,3,5,4,7]
输出: 2
解释: 有两个最长递增子序列,分别是 [1, 3, 4, 7] 和[1, 3, 5, 7]。

Example 2:

输入: [2,2,2,2,2]
输出: 5
解释: 最长递增子序列的长度是1,并且存在5个子序列的长度为1,因此输出5。

Note: The length of the given array does not exceed 2000 and the result must be a 32-bit signed integer.

The question of "the longest increasing subsequence" who asks to find the length of the longest subsequence is to find the number.

Ideas :

First, define the meaning of the dp array:

len[i]Expressed as nums[i]the number of 结尾the longest sub-sequence length increments

cnt[i]Expressed in nums[i]this number 结尾, and for the longest increasing sequence len[i]number of a combination of

index 0 1 2 3 4 5
nums 1 3 5 4 7 6
len 1 2 3 3 4 4
cnt 1 1 1 1 2 2

To the nums[i]ending, so sure to find than the previous nums[i]low.

cnt[i]= All the front ratios are nums[i]smaller and equal len[i]-1to len[j]the number

For example, the above example:

beggingcnt[3]

  • len[3]-1 Equal to 2

  • Then find the ratio before index 3 is nums[3]=4smaller and dp[j]2nums[j]

  • Finally found one, namelylen[1]=2

  • Thereforecnt[3]=1

In a nutshell is: cnt[i]equal len[j]number, but this len[j]should meet three conditions:

  1. i < j
  2. nums[j] < nums[i]
  3. len[j] == len[i] -1

The final result:

  • len[]The maximum value obtained first MAX
  • Returns all len[]equal to MAX corresponding to the index cnt, and

The final code is as follows:

class Solution {
    
    
    public int findNumberOfLIS(int[] nums) {
    
    
        int LEN = nums.length;
        int[] len = new int[LEN];
        int[] cnt = new int[LEN];
        Arrays.fill(len, 1);
        Arrays.fill(cnt, 1);
    
        for(int i = 1; i < LEN; i++){
    
    
            for(int j = 0; j < i; j++){
    
    
                if(nums[j] < nums[i]){
    
    
                    if(len[j] > len[i] - 1){
    
    
                        len[i] = len[j] + 1;
                        cnt[i] = cnt[j];
                    }else if(len[j] == len[i] - 1){
    
    
                        cnt[i] += cnt[j];
                    }
                }
                
            }
        }
        // 只需遍历一遍就可找出dp数组中最大值的个数
        int MAX = 0; // 保存当前最大值
        int res = 0;  // 保存当前最大值的个数
        for(int i = 0; i < LEN; i++){
    
    
            MAX = Math.max(MAX, len[i]);
        }
        for(int i = 0; i < LEN; i++){
    
    
            if(len[i] == MAX){
    
    
                res += cnt[i];
            }
        }
        return res;
        
    }
}

Time complexity: O(N^2)
Space complexity: O(N)

Guess you like

Origin blog.csdn.net/weixin_44471490/article/details/109054664