1. 问题描述:
给定一个未排序的整数数组,找到最长递增子序列的个数。
示例 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。
2. 问题分析:
- 在一个给定的未排序数组中,找到最长递增子序列的个数。在此需要注意的是,最长递增子序列没有要求必须是连续的(只要在数组中是递增的,两个数之间可以有其他数字间隔);
- 我们可以自己创建两个新的数组 length[ nums.length ](length[ i ] 用来存放以nums[ i ] 结尾的子序列的长度),count[ nums.length ](用来存放以nums[ i ]结尾,长度为length[ i ] 的子序列的个数 );
- 对于每一个 i > j 和每一个 nums[ i ] > nums[ j ],我们可以将 nums[ i ] 追加到以 nums[ j ] 结尾的最长子序列上;
- 如果 length[ j ] >= length[ i ](即:以nums[ j ] 结尾的最长子序列的长度大于以 nums[ i ] 结尾的最长子序列的长度),那么我们就可以将 count[ j ] 赋值给 count[ i ];如果 length[ j ] + 1 等于 length[ i ](即:若将 nums[ i ] 追加到以 nums[ j ] 结尾的最长子序列后,则以 nums[ i ] 结尾的最长子序列的长度将等于原有的以 nums[ i ] 结尾的最长子序列的长度),那么我们就可以得到 count[ i ] = count[ i ] + count[ j ]。
3. 代码实现:
class Solution {
public int findNumberOfLIS(int[] nums) {
int leng = nums.length;
//若nums[]的长度小于等于1,则直接返回数组的长度
if(leng <= 1) return leng;
//创建两个数组 length[ ]用于存放长度,count[ ]用于存放子序列的个数
int length[] = new int[leng];
int count[] = new int[leng];
//将初始值置为1
Arrays.fill(length,1);
Arrays.fill(count,1);
for(int i = 1; i < leng; i++) {
for(int j = 0; j < i; j++) {
if(nums[i] > nums[j]) { //首先保证nums[i] > nums[j]
if(length[j] >= length[i]) {
//length[j] >= length[i],以nums[i]结尾的子序列长度将在length[j]的基础上+1,count[i]与count[j]相等
length[i] = length[j] + 1;
count[i] = count[j];
} else if((length[j] + 1) == length[i]) {
//以nums[i]结尾的子序列将在原有的基础上+count[j]
count[i] += count[j];
}
}
}
}
//longest 表示最长子序列的长度,result 表示总个数
int longest = 0,result = 0;
for(int temp : length) {
longest = Math.max(longest,temp);
}
for(int i = 0; i < leng; i++) {
if(length[i] == longest) {
result += count[i];
}
}
return result;
}
}
小熊的分享结束啦!!!