解法一 DP O(n^2)
class Solution {
public:
int maxEnvelopes(vector<pair<int, int>>& envelopes) {
sort(envelopes.begin(), envelopes.end());
int n = envelopes.size();
int res = 0;
vector<int> dp(n, 1);
for(int i=0;i<n;i++){
for(int j=0;j<i;j++){
if(envelopes[j].first<envelopes[i].first && envelopes[j].second<envelopes[i].second)
dp[i] = max(dp[i], dp[j]+1);
}
res = max(res, dp[i]);
}
return res;
}
};
解法二 Binary Search O(n logn)
如何将这道题转化为Longest Increasing Subsequence
从小到大排序宽,从大到小排高,然后此题就变成求高的Longest Increasing Subsequence
Why? 我们需要宽高分别从大到小并且不包括相等的情况。宽已经符合条件除了相等的时候,但是把高从大到小排之后就避免了这种情况。
如何利用binary search找Longest Increasing Subsequence?
维护一个vector,每一个元素代表 increasing substring position i 上最小的数
update: 小于首元素代替,大于末元素加在末尾,大于首元素小于末元素代替第一个比它大的元素
注:这个维护的vector并非最后的increasing substring,只是元素个数相同
class Solution {
public:
int maxEnvelopes(vector<pair<int, int>>& envelopes) {
sort(envelopes.begin(), envelopes.end(), [](const pair<int,int> &a, const pair<int,int> &b){
return a.first<b.first || (a.first==b.first && a.second>b.second);
});
int n = envelopes.size();
vector<int> dp;
for(int i=0;i<n;i++){
int t = envelopes[i].second;
int l=0, r=dp.size();
while(l<r){
int mid = l+(r-l)/2;
if(t>dp[mid]) l=mid+1;
else r=mid;
}
if(r==dp.size()) dp.push_back(t);
else dp[r] = t;
}
return dp.size();
}
};