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)

Example:
Given envelopes = [[5,4],[6,4],[6,7],[2,3]], the maximum number of envelopes you can Russian doll is 3 ([2,3] => [5,4] => [6,7]).

这道题给了我们一堆大小不一的信封,让我们像套俄罗斯娃娃那样把这些信封都给套起来,这道题实际上是之前那道Longest Increasing Subsequence的具体应用,而且难度增加了,从一维变成了两维,但是万变不离其宗,解法还是一样的,首先来看DP的解法,这是一种brute force的解法,首先要给所有的信封按从小到大排序,首先根据宽度从小到大排,如果宽度相同,那么高度小的再前面,这是STL里面sort的默认排法,所以我们不用写其他的comparator,直接排就可以了,然后我们开始遍历,对于每一个信封,我们都遍历其前面所有的信封,如果当前信封的长和宽都比前面那个信封的大,那么我们更新dp数组,通过dp[i] = max(dp[i], dp[j] + 1)。然后我们每遍历完一个信封,都更新一下结果res,参见代码如下;

解法一:

class Solution {
public:
int maxEnvelopes(vector<pair<int, int>>& envelopes) {
int res = , n = envelopes.size();
vector<int> dp(n, );
sort(envelopes.begin(), envelopes.end());
for (int i = ; i < n; ++i) {
for (int j = ; j < i; ++j) {
if (envelopes[i].first > envelopes[j].first && envelopes[i].second > envelopes[j].second) {
dp[i] = max(dp[i], dp[j] + );
}
}
res = max(res, dp[i]);
}
return res;
}
};

我们还可以使用二分查找法来优化速度,我们首先要做的还是给信封排序,但是这次排序和上面有些不同,信封的宽度还是从小到大排,但是宽度相等时,我们让高度大的在前面。那么现在问题就简化了成了找高度数字中的LIS,完全就和之前那道Longest Increasing Subsequence一样了,所以我们还是使用之前那题解法来做,参见代码如下:

解法二:

class Solution {
public:
int maxEnvelopes(vector<pair<int, int>>& envelopes) {
vector<int> dp;
sort(envelopes.begin(), envelopes.end(), [](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;
});
for (int i = ; i < envelopes.size(); ++i) {
int left = , right = dp.size(), t= envelopes[i].second;
while (left < right) {
int mid = left + (right - left) / ;
if (dp[mid] < t) left = mid + ;
else right = mid;
}
if (right >= dp.size()) dp.push_back(t);
else dp[right] = t;
}
return dp.size();
}
};

既然可以用二分查找法,那么使用STL的自带函数lower_bound也没啥问题了,参见代码如下:

解法三:

class Solution {
public:
int maxEnvelopes(vector<pair<int, int>>& envelopes) {
vector<int> dp;
sort(envelopes.begin(), envelopes.end(), [](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;
});
for (int i = ; i < envelopes.size(); ++i) {
auto it = lower_bound(dp.begin(), dp.end(), envelopes[i].second);
if (it == dp.end()) dp.push_back(envelopes[i].second);
else *it = envelopes[i].second;
}
return dp.size();
}
};

讨论:这道题的一个follow up是信封可以旋转,怎么的最长序列?答案是<3,4>加入,然后<4,3>也加入,再找最长序列。

类似题目:

Longest Increasing Subsequence

参考资料:

https://leetcode.com/discuss/106836/simple-dp-solution

https://leetcode.com/discuss/106838/c-dp-version-time-o-n-2-space-o-n

https://leetcode.com/discuss/106888/java-answer-n-lg-n-time-using-binary-search

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Russian Doll Envelopes 俄罗斯娃娃信封的更多相关文章

  1. 354 Russian Doll Envelopes 俄罗斯娃娃信封

    You have a number of envelopes with widths and heights given as a pair of integers (w, h). One envel ...

  2. LeetCode "Russian Doll Envelopes"

    An intuitive DP - should be 'medium'. class Solution { public: int maxEnvelopes(vector<pair<in ...

  3. [LeetCode] 354. Russian Doll Envelopes 俄罗斯套娃信封

    You have a number of envelopes with widths and heights given as a pair of integers (w, h). One envel ...

  4. [Swift]LeetCode354. 俄罗斯套娃信封问题 | Russian Doll Envelopes

    You have a number of envelopes with widths and heights given as a pair of integers (w, h). One envel ...

  5. leetCode 354. Russian Doll Envelopes

    You have a number of envelopes with widths and heights given as a pair of integers (w, h). One envel ...

  6. leetcode@ [354] Russian Doll Envelopes (Dynamic Programming)

    https://leetcode.com/problems/russian-doll-envelopes/ You have a number of envelopes with widths and ...

  7. 【leetcode】354. Russian Doll Envelopes

    题目描述: You have a number of envelopes with widths and heights given as a pair of integers (w, h). One ...

  8. 动态规划——Russian Doll Envelopes

    这个题大意很好理解,通过例子就能明白,很像俄罗斯套娃,大的娃娃套小的娃娃.这个题是大信封套小信封,每个信封都有长和宽,如果A信封的长和宽都要比B信封的要大,那么A信封可以套B信封,现在给定一组信封的大 ...

  9. 354. Russian Doll Envelopes

    You have a number of envelopes with widths and heights given as a pair of integers (w, h). One envel ...

随机推荐

  1. 分布式服务协调员zookeeper - 应用场景和监控

    zookeeper在分布式系统中作为协调员的角色,可应用于Leader选举.分布式锁.配置管理等服务的实现.以下我们从zookeeper提供的API.应用场景和监控三方面学习和了解zookeeper( ...

  2. js模块定义——支持CMD&AMD&直接加载

    /* animate */ //直接加载 (function() { var animate = {} //balabala window.animate = animate; })(); //AMD ...

  3. 匹夫细说C#:庖丁解牛聊委托,那些编译器藏的和U3D给的

    0x00 前言 由于工作繁忙所以距离上一篇博客已经过去一个多月的时间了,因此决心这个周末无论如何也得写点东西出来,既是总结也是分享.那么本文主要的内容集中在了委托的使用以及内部结构(当然还有事件了,但 ...

  4. HTML5 网络拓扑图整合 OpenLayers 实现 GIS 地图应用

    在前面<百度地图.ECharts整合HT for Web网络拓扑图应用>我们有介绍百度地图和 HT for Web 的整合,我们今天来谈谈 OpenLayers 和 HT for Web  ...

  5. 学C#之设计模式系列笔记(2)观察者模式

    一.借鉴说明 1.<Head First Design Patterns>(中文名<深入浅出设计模式>) 2.维基百科,观察者模式,https://zh.wikipedia.o ...

  6. sqlServer去除字段中的中文

    很多时候数据库表中某些字段是由中文和字母或数字组成,但有时我们又需要将字段中的中文去掉.想要实现这种需求的方法有很多,下面就是其中一种解决方法. 首先我们先建立测试数据 create table te ...

  7. Maven远程仓库的配置

    在很多情况下,默认的中央仓库无法满足项目的需求,可能项目需要的构件存在于另外一个远程仓库中,如JBoss Maven仓库.这时,可以在POM中配置该仓库,见代码如下: <!-- 远程仓库的配置 ...

  8. linux使用wkhtmltopdf报错error while loading shared libraries:

    官网提示 linux需要这些动态库.depends on: zlib, fontconfig, freetype, X11 libs (libX11, libXext, libXrender) 在li ...

  9. 网站logo正确写法,个人拙见,不喜勿喷

    网站logo既要考虑seo又需要用图片代替网站名字,所有H1标签带来的权重还是需要使用 有些人喜欢直接把<H1></H1>标签直接hidden掉,个人喜欢使用css Text- ...

  10. LDAP注入与防御解析

    [目录] 0x1 LDAP介绍 0x2 LDAP注入攻击及防御 0x3 参考资料 0x1 LDAP介绍 1 LDAP出现的背景 LDAP(Lightweight Directory Access Pr ...