题目描述:
Given an unsorted array of integers, find the number of longest increasing subsequence.
Example 1:
Input: [1,3,5,4,7] Output: 2 Explanation: The two longest increasing subsequence are [1, 3, 4, 7] and [1, 3, 5, 7].
Example 2:
Input: [2,2,2,2,2] Output: 5 Explanation: The length of longest continuous increasing subsequence is 1, and there are 5 subsequences' length is 1, so output 5. Note: Length of the given array will be not exceed 2000 and the answer is guaranteed to be fit in 32-bit signed int.
思路:
我们已经做过最长递增子序列了https://blog.csdn.net/orangefly0214/article/details/89343811
本题就是在最长递增子序列的基础上增加了条件,让我们计算最长的子序列的个数。
我们以dp[i]表示nums[i]为结尾的的递增序列的长度,
以cnt[i]表示以nums[i]为结尾的递增序列的个数。初始值 设为1,因为只要有数,那最长递增子序列及其个数都至少为1.
对递增序列的判断和300题一样,逐个各边nums中的每个元素,每遍历到一个元素i,都将它前面的每个元素与它作比较:
若nums[i]<nums[j],则dp数组和cnt数组都不做任何改变,因为这种情况下并不会构成递增序列;
若nums[i]>nums[j],此时我们需要判断dp[i]与dp[j]的关系:
若dp[i]<dp[j]+1,此时说明我们在原来长度的基础上找到一条更长的序列,
此时dp[i]=dp[j+1],此时i所对应的最长递增子序列的个数和j对应的是一样的,cnt[i]=cnt[j]。(因为新增的这个序列是在原序列的基础上增加的。)
若dp[i]=dp[j]+1,则说明以dp[j]+1为长度的最长递增子序列已经被上一个j更新过了,此时又相等,说明当前这个j和上一个j都能构成长度为dp[j]+1的最长递增子序列。
比如:
实现:
import java.util.Arrays;
class Solution {
public int findNumberOfLIS(int[] nums) {
int n=nums.length;
int max_len=1;
int[] dp=new int[n];
int[] cnt=new int[n];
Arrays.fill(dp,1);
Arrays.fill(cnt,1);
for(int i=1;i<n;i++){
for(int j=0;j<i;j++){
if(nums[j]<nums[i]&&dp[j]+1>dp[i]){
dp[i]=dp[j]+1;
cnt[i]=cnt[j];
}else if(nums[j]<nums[i]&&dp[j]+1==dp[i]){
//此时说明dp[i]已经被上一个j更新过了,也意味着出现了一个新的能使当前长度达到dp[i] 的值
cnt[i]+=cnt[j];
}
}
max_len=Math.max(dp[i],max_len);
}
int ret=0;
for(int i=0;i<n;i++){
if(dp[i]==max_len){
ret+=cnt[i];
}
}
return ret;
}
}