概述
602. Russian Doll Envelopes
Give 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.
Find the maximum number of nested layers of envelopes.
Example
Example 1:
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]).
Example 2:
Input:[[4,5],[4,6],[6,7],[2,3],[1,1]]
Output:4
Explanation:
the maximum number of envelopes you can Russian doll is 4 ([1,1] => [2,3] => [4,5] / [4,6] => [6,7]).
Input test data (one parameter per line)How to understand a testcase?
这题跟LintCode 1858: Set of boxes 很相似,1858那题比这题还要稍微难一点,因为还要根据x和y再排一下序,这道题不用,因为x就跟x相比,y就跟y相比。详见https://blog.csdn.net/roufoo/article/details/105097818。
解法1:类似LIS,但超时。
注意:
1) 这里的sort是pair<int, int>的default版本。
2) 这里dp[]并不一定是从小到大排序,也就是说dp[n-1]不一定是最优解。
class Solution {
public:
/*
* @param envelopes: a number of envelopes with widths and heights
* @return: the maximum number of envelopes
*/
int maxEnvelopes(vector<pair<int, int>>& envelopes) {
int n = envelopes.size();
if (n == 0) return 0;
sort(envelopes.begin(), envelopes.end());
vector<int> dp(n, 1);
int gMaxLevel = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < i; ++j) {
if (envelopes[i].first > envelopes[j].first &&
envelopes[i].second > envelopes[j].second) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
gMaxLevel = max(gMaxLevel, dp[i]);
}
for (int i = 0; i < n; ++i) cout<<dp[i]<<" ";
cout<<endl;
return gMaxLevel;
}
};
解法2:单调递增队列
注意:
1) 排序的时候按第一维排序,若第一维相等则按第二维。
为什么呢?假设排序后队列如下:
(1,8)
(2,3)
(5,4)
(5,2)
(6,7)
(6,4)
为什么第2维要降序呢?因为看下面的例子,(5,4)排在(5,2)前面。单调递增队列轮到(5,2)的时候,binary search返回的序号就是(5,4)的序号(lower_bound,按y来搜索),所以它会踢掉(5,4)。如果第2维升序的话,那么(5,2)排在(5,4)前面,单调递增队列先把(5,2)放进来,再看(5,4)的时候因为4>2,所以(5,4)也会放进队列,这样队列里面有2个箱子第1维都是5,就不对了。
2) lower_bound是返回an iterator pointing to the first element in the range [first,last)
which does not compare less than val, 所以不需要重新定义binary search函数了。
3) 不能直接重载bool operator < (const pair<int, int> & a, const pair <int, int> & b),
然后sort(envelops.begin(), envelops.end())。这样重载的operator < 根本没有调用到。原因应该是pair<int,int>是内置类型,不能重载操作符。应该加一个wrapper class。或者重新定义一个Node结构,重载bool operator<是可以的。
struct compare {
bool operator () (const pair<int, int> & a, const pair<int, int> & b) {
if (a.first == b.first) return a.second > b.second;
return a.first < b.first;
}
}cmp;
class Solution {
public:
/*
* @param envelopes: a number of envelopes with widths and heights
* @return: the maximum number of envelopes
*/
int maxEnvelopes(vector<pair<int, int>>& envelopes) {
int n = envelopes.size();
if (n == 0) return 0;
sort(envelopes.begin(), envelopes.end(), cmp);
vector<int> monoIncSeqs;
for (int i = 0; i < n; ++i) {
vector<int>::iterator it = lower_bound(monoIncSeqs.begin(), monoIncSeqs.end(), envelopes[i].second);
if (it == monoIncSeqs.end()) {
monoIncSeqs.push_back(envelopes[i].second);
} else {
*it = envelopes[i].second;
}
}
return monoIncSeqs.size();
}
};
也可以写成:
struct compare {
bool operator () (const pair<int, int> & a, const pair<int, int> & b) {
if (a.first == b.first) return a.second > b.second;
return a.first < b.first;
}
}cmp;
class Solution {
public:
/*
* @param envelopes: a number of envelopes with widths and heights
* @return: the maximum number of envelopes
*/
int maxEnvelopes(vector<pair<int, int>>& envelopes) {
int n = envelopes.size();
if (n == 0) return 0;
sort(envelopes.begin(), envelopes.end(), cmp);
vector<int> monoIncSeqs(n, INT_MAX);
for (int i = 0; i < n; ++i) {
vector<int>::iterator it = lower_bound(monoIncSeqs.begin(), monoIncSeqs.end(), envelopes[i].second);
*it = envelopes[i].second;
}
for (int i = n - 1; i >= 0; --i) {
if (monoIncSeqs[i] != INT_MAX) return i + 1;
}
return 0;
}
};
最后
以上就是过时路灯为你收集整理的LintCode 602: Russian Doll Envelopes (俄罗斯套娃,单调队列经典题)的全部内容,希望文章能够帮你解决LintCode 602: Russian Doll Envelopes (俄罗斯套娃,单调队列经典题)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复