Leetcode 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.
Note:Length of the given array will be not exceed 2000 and the answer is guaranteed to be fit in 32-bit signed int.
题意分析
本题可以分解为一个更简单的问题,寻找最长递增序列的长度,这个问题可以采用动态规划方法,令一个数组L[N],L[i]表示以nums[i]结尾的最大递增序列的长度。要注意原序列可能有多个长度达到最长的递增子序列,每个序列一定以nums中某个元素为结尾。
解法分析
本题采用自底向上动态规划方法,首先解决最长递增序列长度的问题,用L[N]存储以nums每一位结尾的递增子序列的最长长度,递归式如下:
为了在最后能得到最长序列的个数,需要利用另一个数组M[N]存储以nums[i]结尾的最长序列的个数。C++代码如下:
class Solution {
public:
int findNumberOfLIS(vector<int>& nums) {
int n=nums.size();
if(n==0)
return 0;
vector<int> L(n,1);//L[i] is the length of the longest substr that contains nums[i]
vector<int> M(n,1);//M[i] is the number of str end with nums[i] and the length reaches L[i];
int i,j;
int temp=1;
for(i=0;i<n;i++){
for(j=0;j<i;j++){
if(nums[j]<nums[i]){
temp=L[j]+1;
if(temp==L[i])
M[i]=M[i]+M[j];//That is important
else if(temp>L[i]){
M[i]=M[j];//That is important
L[i]=temp;
}
}
else
continue;
}
}
//Find the max number in nums,and its count
int count=1;
int maxL=0;
for(i=0;i<n;i++){
if(maxL<L[i]){
count=M[i];
maxL=L[i];
}
else if(maxL==L[i])
count=count+M[i];
}
return count;
}
};
if(nums[j]<nums[i]){
temp=L[j]+1;
if(temp==L[i])
M[i]=M[i]+M[j];//That is important
else if(temp>L[i]){
M[i]=M[j];//That is important
L[i]=temp;
}
}
上述代码最关键,原因是以某元素a结尾的递增序列可能有n个,如果有一个元素b满足b>a,则对于以a结尾的最长递增序列,由a贡献的序列个数为n;不同元素结尾的最长序列长度可能相同,在计算相应长度序列个数时应把这些都考虑在内。