You have a number of envelopes with widths and heights given as a pair of integers (w, h)
. One envelope can fit into another if and only if both the width and height of one envelope is greater than the width and height of the other envelope.
What is the maximum number of envelopes can you Russian doll? (put one inside other)
Note:
Rotation is not allowed.
Example:
Input: [[5,4],[6,4],[6,7],[2,3]] Output: 3 Explanation: The maximum number of envelopes you can Russian doll is 3 ([2,3] => [5,4] => [6,7]).
分析
这道题可以用动态规划的解法去解决。先对数组进行Width的排序,然后遍历数组,记录每个位置i所能装信封的最大值,然后
dp[i+1] = max(dp[0], ...., dp[i]),记录遍历过程中的最大值即可。时间复杂度为O(n^2)。
看到其他人有一种更为巧妙的解法,可以利用二分查找直接获取位置i的最大值。简单介绍一下就是,排序的时候要求 width1 < width2 || (width1 == width2 && length1 > length2)。在使用dp数组记录当前length的升序排列。而dp作为单调数组的长度就是最终最终的结果。
Code
这里只介绍O(n^2)的算法。
class Solution {
public:
static bool cmp(const vector<int>& a, const vector<int>& b)
{
return a[0] < b[0] || (a[0] == b[0] && a[1] < b[1]);
}
int maxEnvelopes(vector<vector<int>>& envelopes) {
sort(envelopes.begin(), envelopes.end(), cmp);
int length = envelopes.size();
if (length == 0)
return 0;
vector<int> dp(length, 1);
int res = 1;
for (int i = 1; i < length; 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);
}
}
res = max(res, dp[i]);
}
return res;
}
};
运行效率
Runtime: 624 ms, faster than 13.18% of C++ online submissions for Russian Doll Envelopes.
Memory Usage: 14.8 MB, less than 5.95% of C++ online submissions forRussian Doll Envelopes.