300. Longest Increasing Subsequence
Given an unsorted array of integers, find the length of longest increasing subsequence.
Example:
Input: [10,9,2,5,3,7,101,18]
Output: 4
Explanation: The longest increasing subsequence is [2,3,7,101]
, therefore the length is 4
.
Note:
- 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?
题目链接:https://leetcode-cn.com/problems/longest-increasing-subsequence/
思路
法一:dp
存储空间用来记录长度为i串们的最后一个字符,其中最小的值。
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int len = nums.size();
if(len<=1) return len;
int rec[len+1];
for(int i=0; i<=len; ++i){
rec[i] = INT_MAX;
}
rec[1] = nums[0];
int res = 1;
for(int i=1; i<len; ++i){
for(int j=1; j<len; ++j){
if(rec[j]==nums[i]) break;
else if(rec[j]>nums[i]){
rec[j] = nums[i];
res = max(res, j);
break;
}
}
}
if(nums[len-1]>rec[res]) ++res;
return res;
}
};
法二:dp+二分
可以看出,记录空间里的值是递增的,因此在记录空间查找时可以使用二分查找以加快运行速度。
总体思路和法1一样,加了一些优化。
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int len = nums.size();
if(len<=1) return len;
int rec[len+1], res = 1;
for(int i=0; i<len; ++i){
rec[i] = INT_MAX;
}
rec[1] = nums[0];
for(int i=1; i<len; ++i){
if(rec[res]<nums[i]){
rec[++res] = nums[i];
}else{
int l = 1, r = res - 1;
while(l<=r){
int mid = l + (r-l)/2;
if(rec[mid]<nums[i]){
l = mid+1;
}else {
r = mid-1;
}
}
rec[l] = nums[i];
}
}
return res;
}
};