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.
n^2复杂度使用动态规划即可,先求出第一个数对应的值,后一个数就可以比较前面的数来确定自己的值。循环比较就可以得到结果
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int len = nums.size();
if(len < 1){
return 0;
}
vector<int> dp(len, 1);
int res=1;
for(int i=0; i<len; i++){
for(int j=0; j<i; j++){
if(nums[i]>nums[j]){
dp[i]=max(dp[j]+1, dp[i]);
}
}
res =max(res,dp[i]);
}
return res;
}
};
nlogn复杂度
比如这个[10, 9, 2, 5, 3, 7, 101, 18]中,
当我们计算7的时候,3可以取代5, 而且比5更好。
原因,
第一,3<5只有比5大的数必定大于3,最大结果不变。
第二,3和5的暂时长度一样,用3代替5不影响暂时长度。
若是[10, 9, 2, 4, 5, 3, 7, 101, 18],5之前多了一个4,3和5就存在暂时长度不同了,那么我们此时可以将4替换成3。其结果也是不变了。
基于如此,使用这种取代的方法,我们申请一个数组res,从nums中拿出一个数,就和res比,如果比res里面的都大,那么这就是个递增的,我们就push进去,如果就比其中部分值大,那么我们就替换掉那个刚好比他大的那个数,如同上面的3将5替换掉不影响结果,循环直至结束,res的长度就是最大值。
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
vector<int> res;
for(int i=0; i<nums.size(); i++){
auto it = std::lower_bound(res.begin(),res.end(), nums[i]);
if(it == res.end()){
res.push_back(nums[i]);
}else{
*it = nums[i];
}
}
return res.size();
}
};