俄罗斯套娃信封问题
给定一些标记了宽度和高度的信封,宽度和高度以整数对形式 (w, h) 出现。当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。
请计算最多能有多少个信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。
说明:
不允许旋转信封。
示例:
输入: envelopes = [[5,4],[6,4],[6,7],[2,3]]
输出: 3
解释: 最多信封的个数为 3, 组合为: [2,3] => [5,4] => [6,7]。
动态规划,这个方法求解很慢,但是我只会这一种
#include <vector> #include <iostream> #include <algorithm> using namespace std; bool compare(vector<int> A, vector<int> B) { if (A[0] == B[0]) return A[1] < B[1]; return A[0] < B[0]; } class Solution { public: int maxEnvelopes(vector<vector<int>> &envelopes) { sort(envelopes.begin(), envelopes.end(), compare); int n = envelopes.size(); if (n == 0) return 0; vector<int> dp(n, 1); for (int i = 0; i < n; ++i) { for (int j = 0; j < i; ++j) { if ((envelopes[i][0] > envelopes[j][0]) && (envelopes[i][1] > envelopes[j][1])) dp[i] = max(dp[i], dp[j] + 1); } } return *max_element(dp.begin(), dp.end()); } }; int main() { vector<vector<int>> nums{{5, 4}, {6, 4}, {6, 7}, {2, 3}}; Solution s; cout << s.maxEnvelopes(nums) << endl; }

这里补上一位大佬的二分法
class Solution { private: // 最长递增子序列的求解 int LengthOfLIS(vector<int>& nums) { int n = nums.size(); if (n == 0) { return 0; } // 最大的长度记录 int len = 1; // 直接预留了一,所以是n+1 填充时候也从1开始 int* d = new int[n+1]; d[len] = nums[0]; for (int i = 1; i < n; ++i) { // 递增则直接放在最后面 if (nums[i] > d[len]) { d[++len] = nums[i]; } else { // 二分法,找到这个可以更新的位置,但不破坏原来的顺序 int l = 1; int r = len; // pos定位为比nums[i]小的数的位置,如果找不到 pos 就是0,对应更新的是 pos+1 // 这里核心思想就是一直维持数组的递增的顺序 依靠len最大化来保存结果 // 而如果后续有更多递增数字,则会继续扩大递增的数组,len继续增大 int pos = 0; while (l <= r) { int mid = (l + r) >> 1; if (d[mid] < nums[i]) { pos = mid; l = mid + 1; } else { r = mid - 1; } } d[pos + 1] = nums[i]; } } return len; } public: int maxEnvelopes(vector<vector<int>>& envelopes) { // 按照第一维升序排列, 第二维相等的时候 第二维降序排列 sort(envelopes.begin(), envelopes.end(), [](const vector<int>& a, const vector<int>& b) { if (a[0] != b[0]) { return a[0] < b[0]; } else { return a[1] >= b[1]; } }); int n = envelopes.size(); vector<int> nums(n); for (int i = 0; i < n; ++i) { nums[i] = envelopes[i][1]; } return LengthOfLIS(nums); } }; 作者:ffreturn 链接:https://leetcode-cn.com/problems/russian-doll-envelopes/solution/c999de-zui-da-di-zeng-zi-xu-lie-de-jie-f-apzw/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
浙公网安备 33010602011771号