题目链接为:Number of Longest Increasing Subsequence
题目要求很简单:给出一个无序的整数数组,找出最长递增子序列的个数。并给了两个样例:
样例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].
样例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.
这种问题可以通过动态规划来解决,根据题目的要求,我们要记录以第i个元素结尾的最长递增子序列的长度,我们记为dp_0[i],同时记录以第i个元素结尾的最长递增子序列的个数,记为dp_1[i],
伪代码为:
/*nums = an unsorted array of integers
**size = the size of nums
*/
max_len = 1 //initialize the max length of increasing subsequence to be 1
for i from 0 to n-1:
count = 0
dp_0[i] = dp_1[i] = 1;
for j from 0 to i-1:
if nums[j] < nums[i]:
if dp_0[i] < dp_0[j]:
dp_0[i] = dp_0[j] + 1
count = 0
if dp_0[i] == dp_0[j] + 1:
count += dp_1[j]
dp_1[i] = max(dp_1[i], count)
max_len = max(dp_0[i],max_len)
result = the sum of all dp_0[i] which is equal to max_len
return result
算法的C++实现:
class Solution {
public:
int findNumberOfLIS(vector<int>& nums) {
int n = nums.size();
int *dp_0 = new int[n];//dp_0[i]表示以第i个元素结尾的最长上升子序列的长度
int *dp_1 = new int[n];//dp_1[i]表示对应的以第i个元素结尾的最长上升子序列的个数
int max_len = 1;
int res = 0;
for(int i = 0; i < n; i++){
int count = 0;
dp_0[i] = dp_1[i] = 1;
for(int j = 0; j < i; j++){
if(nums[j] < nums[i]){
if(dp_0[i] < dp_0[j] + 1) {
dp_0[i] = dp_0[j] + 1;//更新当前最长上升子序列的长度
count = 0;//由于有更长的子序列,所以重置count为0
}
if(dp_0[i] == dp_0[j] + 1){
count += dp_1[j];
}
}
}
dp_1[i] = max(count,dp_1[i]);
max_len = max(max_len,dp_0[i]);
}
for(int i = 0; i < n; i++){
if(max_len == dp_0[i]){
res += dp_1[i];
}
}
return res;
}
};