题目描述
做题思路
如果对这道题一点都不懂可以先看下面这道题
最长递增子序列的个数只是比最长递增子序列多加了一项求子序列数量的要求
只需在原来代码的基础上多加一个数组num[i]记录以nums[i]结尾的最长递增子序列的数量
一样先从i=1开始遍历数组nums[]与前面的数比较如果nums[i]>nums[j] 1<=i<nums.length
0<=j<i
意味着nums[i]可以接在nums[j]后面产生新的子序列
假如当前记录的以nums[i]结尾的最长递增子序列的长度为n
这样长度的序列有m个 即 当前dp[i]=n num[i]=m
新产生的递增子序的长度为k k= dp[j]+1
接下来分三种情况
1. k<n
那么最长子序列的长度及数量均没有变化
2. k==n
说明新的序列和以前记录的最长递增序列一样长,
那么最长递增序列的长度不变,数量加上新产生的子序列的数量num[j] 即num[i]=num[i]+num[j]
3. k>n
说明新产生的序列的长度大于当前记录的最长递增子序列的长度
那么最长递增子序列的长度和数量都将变化, 长度变dp[i]=num[j]+1 数量为新产生序列的数量
num[i]=num[j]
代码
class Solution {
public int findNumberOfLIS(int[] nums) {
int[] a=nums;
int len =a.length;
//dp[i]记录的是以a[i]为结尾的最长子序列的长度 状态转移方程 if a[i]>a[j] dp[i]= max(dp[j]+1,dp[i]) j->[0:i)
//num[i]记录的是以a[i]为结尾的最长字符串的个数 状态转移方程if dp[i]=dp[j]+1 num[i]+=num[j] if dp[i]<dp[j]+1 num[i]=num[j] j->[0,i)
//用sum时刻更新最长子序列的长度
int[] dp=new int[len];
int[] num=new int[len];
Arrays.fill(dp,1);
Arrays.fill(num,1);
int sum=1;
for (int i=1;i<len;i++){
for (int j=0;j<i;j++){
if (a[i]>a[j]){
if (dp[i]==dp[j]+1){
num[i]+=num[j];
}else if (dp[i]<dp[j]+1){
dp[i]=dp[j]+1;
num[i]=num[j];
}
}
}
sum=Math.max(sum,dp[i]);
}
int maxl=0;
for(int i=0;i<len;i++){
if(dp[i]==sum)
{
maxl+=num[i];
}
}
return maxl;
}
}