给你一个二维整数数组 envelopes ,其中 envelopes[i] = [wi, hi]
,表示第 i 个信封的宽度和高度。
当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。
请计算 最多能有多少个
信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。
注意:不允许旋转信封。
示例:
输入:envelopes = [[5,4],[6,4],[6,7],[2,3]]
输出:3
解释:最多信封的个数为 3, 组合为: [2,3] => [5,4] => [6,7]。
思路:
我们首先想到的肯定是排序,假设信封是有由(w,h)
这样的二维数对组成。
我们先按照宽度w
进行升序排序,如果遇到w
相同的情况,则按照高度h
降序排序。最后把所有的h
组成一个新的数组,进行最长递增子序列。就是最后的答案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| class Solution { public: int maxEnvelopes(vector<vector<int> >& envelopes) { int n = envelopes.size(); sort(envelopes.begin(), envelopes.end(), [](const vector<int>& e1, const vector<int>& e2){ if(e1[0] == e2[0]) return e1[1] > e2[1]; return e1[0] < e2[0]; }); vector<int> height(n); for(int i = 0; i < n; i++){ height[i] = envelopes[i][1]; } return lengthOfLIS(height); } int lengthOfLIS(vector<int>& nums) { vector<int> top(nums.size(), 0); int piles = 0; for(int i = 0; i < nums.size(); i++){ int poker = nums[i];
int left = 0, right = piles; while(left < right){ int mid = (left + right) / 2; if(top[mid] > poker){ right = mid; }else if(top[mid] < poker){ left = mid + 1; }else{ right = mid; } }
if(left == piles) piles++; top[left] = poker; } return piles; } };
|