给定一个未排序的整数数组,找到最长递增子序列的个数。
示例 1:
输入: [1,3,5,4,7] 输出: 2 解释: 有两个最长递增子序列,分别是 [1, 3, 4, 7] 和[1, 3, 5, 7]。
示例 2:
输入: [2,2,2,2,2] 输出: 5 解释: 最长递增子序列的长度是1,并且存在5个子序列的长度为1,因此输出5。
注意: 给定的数组长度不超过 2000 并且结果一定是32位有符号整数。
Related Topics
参考之前的LeetCode刷题【300】最长递增子序列这题,用动态规划的话先拿出原来的代码看下
class Solution {
public int lengthOfLIS(int[] nums) {
int[] dp = new int[nums.length];
int max = 0;
for (int i = 0; i < nums.length; i++) {
dp[i] = 1;
for (int j = 0; j < i; j++) {
if (nums[i]<=nums[j]){
continue;
}
dp[i] = Math.max(dp[j]+1,dp[i]);
}
max = Math.max(max,dp[i]);
}
return max;
}
}
在原来的dp数组记录的到达每个位置的时候,需要额外的增加一个数组int[] count来记录当前位置的最大值,下面以数组[1,2,4,3,5,4,7,2]为例
- 第一位的时候,dp[0] = 1,count[0] = 1,显然的第一位的时候递增子序列长度为1,就是自身,可能的子序列组合也只有一种
- 当索引1的时候,dp[1] = 2,count[1] = 1,因为当前位置上的值2比前面的1大,构成新的最长递增子序列,所以长度增加,组合情况也只有1种
- 当索引2的时候,此时的值为4,依次从头开始遍历后,可以知道最大递增子序列长度为3,最大递增子序列组合数为1。
- 当索引3的时候,此时的值为3,只能喝前面的2组成最大递增子序列,同样的和末尾为4的时候的组合长度一样,最大递增子序列长度为3,当前位置以数字3结尾的组合只有[1,2,3]一种,所以count[3] = 3
- 当索引4的时候,当前位置数字位5,以5结尾的最大递增子序列的可以为[1,2,4,5]或者[1,2,3,5],显然的此时的dp[4]可以由原来的dp[2]+1 也可以由dp[3]+1得到,那么当遍历到索引2的时候可以得到dp[4] = dp[2]+1,此时同时把count[4] = count[2],之后再次遇到dp[3]+1 == dp[4]的时候,count[4] 应该等于count[3]+count[4]的合。即dp[4] = 4 ,count[4] = 2
- 当索引5的时候位置上的值为4,能和前面的组成[1,2,3,4]最大递增子序列,其dp值依赖于前面的值3的索引处的dp,即dp[5] = dp[3]+1 = 4,子序列个数同样继承count[5] = count[3] = 1,那么这个时候,我们在遍历比价max的时候就会发现和前面的索引4位置求到的max值相等,都是4,这个时候就需要额外记下maxCount = count[4]+count[5] = 2 + 1 = 3;
- 索引6,位置上的值为7,dp值依赖于索引4、5位置上的值,当一开始遍历的索引4的时候dp[6] = dp[4]+1 = 5,count[6] = count[4] = 2,当之后遍历到索引5嘚 时候,dp[5]+1 == dp[6] ,所以count[6] = count[6] + count[5] = 2 + 1 = 3。
- 索引7,值为2,省略不写了
即
数组 | 1 | 2 | 4 | 3 | 5 | 4 | 7 | 2 |
dp[] | 1 | 2 | 3 | 3 | 4 | 4 | 5 | 2 |
count[] | 1 | 1 | 1 | 1 | 2 | 1 | 3 | 1 |
所以代码逻辑基本就出来了
class Solution {
public int findNumberOfLIS(int[] nums) {
int[] dp = new int[nums.length];
int[] count = new int[nums.length];
int maxCount = 0;
int max = 0;
for (int i = 0; i < nums.length; i++) {
dp[i] = 1;
count[i] = 1;
for (int j = 0; j < i; j++) {
if (nums[j] >= nums[i]){
//前面的这个数字比当前数字大,跳过
continue;
}
if (dp[j]+1 > dp[i]){
dp[i] = dp[j]+1;
count[i] = count[j];
}else if (dp[j]+1 == dp[i]){
count[i] += count[j];
}
}
if (max < dp[i]){
max = dp[i];
maxCount = count[i];
}else if (max == dp[i]){
maxCount += count[i];
}
}
return maxCount;
}
}
发表评论