For example,
Given [10, 9, 2, 5, 3, 7, 101, 18]
,
The longest increasing subsequence is [2, 3, 7, 101]
, therefore the length is 4
. Note that there may be more than one LIS combination, it is only necessary for you to return the length.
Your algorithm should run in O(n2) complexity.
Follow up: Could you improve it to O(n log n) time complexity?
长度为N的数组记为A={a0 a1 a2...an-1};
记A的前i个字符构成的前缀串为Ai= a0 a 1a2...ai-1,以ai结尾的最长递增
子序列记做Li,其长度记为a[i];
假定已经计算得到了a[0,1…,i-1],如何计算a[i]呢?
根据定义, Li必须以ai结尾,如果将ai缀到L0 L1…… Li-1的后面,是否
允许呢?
如果aj<ai,则可以将ai缀到Lj的后面,并且使得Lj的长度变长。
从而:a[i]={max(a(j))+1, 0 ≤j≤i-1且a[j]≤a[i] }
需要遍历在i之前的所有位置j,找出满足条件a[j]≤a[i]的a[j];
计算得到a[0…n-1]后,遍历所有的a[i],找出最大值即为最大递增子序列
的长度。
时间复杂度为O(N2)。
思考:如何求最大递增子序列本身?
记录前驱
class Solution {
public int lengthOfLIS(int[] a) {
if(a.length==0) return 0;
int[] longs = new int[a.length];
for(int i = 0;i<a.length;i++)
longs[i] = 1;
int max = longs[0];
for(int i = 1;i < a.length;i++){
for(int j = 0;j <= i-1;j++)
if(a[j]<a[i])
if(longs[i]<longs[j]+1)
longs[i] = longs[j]+1;
//如果求序列本身,在这里记录前驱 if(max<longs[i])
max = longs[i];
}
return max;
}
class Solution {
public:
int lengthOfLIS(vector<int>& a) {
if (a.size()==) return ;
int max = ;
vector<int> dp(a.size(),);
for (int i = ;i < a.size(); i++) {
for (int j = ; j < i ;j++) {
if (a[j] < a[i]) {
dp[i] = std::max(dp[j]+,dp[i]);
}
}
max = std::max(dp[i],max);
} return max;
}
};
class Solution(object):
def lengthOfLIS(self, a):
n = len(a)
if n ==0:
return 0
dp = [1] * n
for i in range(n):
for j in range(i):
if(a[i]>a[j] and dp[i]<dp[j]+1):
dp[i] = dp[j]+1 #dp[i]现在存储的即为以a[i]结尾最长递增子序列长度
#求dp数组中最大者即为最长的长度 return max(dp)