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;
}
};