Given an unsorted array of integers, find the length of longest increasing subsequence.
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?
Credits:
Special thanks to @pbrother for adding this problem and creating all test cases.
Subscribe to see which companies asked this question
动态规划:
f(n+1) = if(nums[n+1]>nums[i]) f(i)+1
if(mums[n+1]<nums[i]) 1 i在[0,n]
f(n+1) = max(f(i))
复杂度O(N^2)
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
if(nums.size()==0)
return 0;
vector<int> Dp(nums.size(),1);
int max = 0;
int ret = 1;
for(int i=1;i<nums.size();++i){
int temp = 1;
for(int j=0; j<i; ++j){
if(nums[i]>nums[j]){
temp = Dp[j]+1;
}
else{
temp = 1;
}
if(temp>max){
max = temp;
}
}
Dp[i] = max;
max = 0;
temp = 0;
if(Dp[i]>ret){
ret = Dp[i];
}
}
return ret;
}
};
更优解法,维护一个最大递增子串:然后通过二分查找搜寻位置:
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
//Here is the explanation of the idea https://www.cs.princeton.edu/courses/archive/spring13/cos423/lectures/LongestIncreasingSubsequence.pdf
// Binary search for the stack where the nums[i] should be pushed, according the tops of the stacks
// nums[i] cannot be push to any stack whose top is less than nums[i].
// The number of stacks is the Length of LIS.
int n = nums.size();
if( n==0 ){
return 0;
}
int end = 0;
vector<int> tops(n, INT_MIN);
tops[0] = nums[0];
for(int i=1; i<n; i++){
int idx = getIndex( tops, end, nums[i] );
tops[idx] = nums[i];
end = max( idx, end );
}
return end+1;
}
};
int getIndex( vector<int>& tops, int end, int x ){
int l = 0;
int r = end;
while( l<=r ){
int mid = (l+r)/2;
if( tops[mid] == x ){
return mid;
}
else if( tops[mid] > x ){
r = mid - 1;
}
else{
l = mid + 1;
}
}
return l;
}