673. Number of Longest Increasing Subsequence
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.
1.解析
题目大意,求解最长子序列的所有个数。
2.分析
整体上看,这道题是最长子序列的升级版。难点就在于如何保存出现多个最长子序列时的个数,参考@Granyang的博客,巧妙的用到了两个dp数组,len[i]表示前i个序列的最长的子序列,cnt[i]表示前i个序列的最长的子序列的个数;如果当前nums[i] <= nums[j],那么不满足递增子序列的定义,无需考虑;反之,则nums[i]可以作为子序列[0, j]的下一个元素,若当前len[i] == len[j] + 1,说明存在多个当前最长子序列,cnt[i] += cnt[j];若当前len[i] < len[j] + 1,说明找到目前最长的子序列,cnt[i] = cnt[j]。最后跟全局的最长子序列mx进行比较,并更新状态即可。
class Solution {
public:
int findNumberOfLIS(vector<int>& nums) {
if (nums.empty()) return 0; //若当前数组为空
int mx = 1, res = 1, n = nums.size(); //最长子序列的长度至少为1,个数也至少有1个
vector<int> len(n, 1), cnt(n, 1);
for (int i = 1; i < n; ++i){
for (int j = i - 1; j >= 0; --j){
if (nums[j] < nums[i]){ //满足递增子序列的定义
if (len[j] + 1 == len[i]) cnt[i] += cnt[j];
else if (len[j] + 1 > len[i]){ //若找到更长的递增子序列,则之前的个数作废,将cnt[j]作为当前最长子序列的个数
len[i] = len[j] + 1;
cnt[i] = cnt[j];
}
}
}
if (mx == len[i]) res += cnt[i]; //跟全局的最长子序列进行比较
else if (mx < len[i]) mx = len[i], res = cnt[i];
}
return res;
}
};