- DP
LIS问题的常规DP即可。 d p [ i ] = d p [ j ] + 1 ( a [ j ] < a [ i ] ) dp[i] = dp[j]+1 (a[j]<a[i]) dp[i]=dp[j]+1(a[j]<a[i])
时间复杂度: O ( n 2 ) O(n^2) O(n2)
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int n = nums.size() ,ans = 0;
if(n==0) return 0;
vector<int> dp(n,1);
for(int i=1;i<n;i++){
for(int j=0;j<i;j++){
if(nums[i]>nums[j]){
dp[i] = max(dp[i],dp[j]+1);
}
}
}
for(int i=0;i<n;i++){
ans = max(ans,dp[i]);
}
return ans;
}
};
- 贪心+二分
时间复杂度: O ( n ∗ l o g ( n ) ) O(n*log(n)) O(n∗log(n))
维护一个单调递增的序列,为了使得最长上升子序列尽可能的长,应该使得整个序列增长的尽可能慢。
比如 [1,7,8,4,6,7]
[1]
[1,7]
[1,7,8]
[1,4,8]
[1,4,6]
[1,4,6,7] 最终长度为4。
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
vector<int> v;
for(int x:nums){
auto it = lower_bound(v.begin(),v.end(),x);
if(it==v.end()){
v.push_back(x);
}else{
v[it-v.begin()] = x;
}
}
return v.size();
}
};
354.俄罗斯套娃信封问题
时间复杂度: O ( n ∗ l o g ( n ) ) O(n*log(n)) O(n∗log(n))
排序相当于二维降一维的操作,然后就是一个LIS的求法。
和这道题很像。最长数对链
class Solution {
public:
static bool cmp(vector<int>& v1,vector<int>& v2){
return v1[0]<v2[0] || (v1[0]==v2[0] && v1[1]>v2[1]);
}
int lengthOfLIS(vector<int>& nums) {
vector<int> v;
for(int x:nums){
auto it = lower_bound(v.begin(),v.end(),x);
if(it==v.end()){
v.push_back(x);
}else{
v[it-v.begin()] = x;
}
}
return v.size();
}
int maxEnvelopes(vector<vector<int>>& pairs) {
int n = pairs.size(), ans = 1;
if(n==0) return 0;
sort(pairs.begin(),pairs.end(),cmp);
vector<int> v;
for(auto&pair:pairs){
v.push_back(pair[1]);
}
return lengthOfLIS(v);
}
};