LeetCode——354. 俄羅斯套娃信封問題
阿新 • • 發佈:2020-12-31
技術標籤:C++leetcode動態規劃演算法動態規劃leetcode資料結構
題目描述:
給定一些標記了寬度和高度的信封,寬度和高度以整數對形式 (w, h) 出現。當另一個信封的寬度和高度都比這個信封大的時候,這個信封就可以放進另一個信封裡,如同俄羅斯套娃一樣。
請計算最多能有多少個信封能組成一組“俄羅斯套娃”信封(即可以把一個信封放到另一個信封裡面)。
說明:
不允許旋轉信封。
示例:
輸入: envelopes = [[5,4],[6,4],[6,7],[2,3]]
輸出: 3
解釋: 最多信封的個數為 3, 組合為: [2,3] => [5,4] => [6,7]。
思路:先對寬度W進行升序排列,如果遇到W相同的情況下,則按照高度H降序排列。之後把所有的H作為一個數組,在這個陣列上計算出的LIS(最長遞增子序列)的長度就是答案。
為什麼要W相同的情況下,則按照高度H降序排列?
因為兩個W相同的信封不能相互包含,W相同的時候將H逆序排列,則這些逆序H中最多隻會有一個被選入遞增子序列,保證了最終的信封序列中不會出現W相同的情況。
程式碼如下:
class Solution {
public:
int maxEnvelopes(vector<vector<int>>& envelopes) {
if(envelopes. size()==0){
return 0;
}
int h=envelopes.size();
int l=envelopes[0].size();
sort(envelopes.begin(), envelopes.end(), [](vector<int>a, vector<int>b) {return a[0]==b[0]?a[1] > b[1]:a[0]<b[0]; });//先對寬度W進行升序排列,如果遇到W相同的情況下,則按照高度H降序排列,這是重點。
vector< int>v;
for(int i=0;i<h;i++){
v.push_back(envelopes[i][1]);
}
return IFS(v);
}
int IFS(vector<int>&v){
int size=v.size();
vector<int>dp(size,1);
int ans=0;
for(int i=0;i<size;i++){
for(int j=0;j<i;j++){
if(v[j]<v[i]){
dp[i]=max(dp[i],dp[j]+1);
}
}
ans=max(ans,dp[i]);
}
return ans;
}
};
執行結果: