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. [AngularJS] AngularJS系列(3) 中级篇之表单验证

    目录 基本验证 验证插件messages 自定义验证 基本验证 <form name="form" novalidate ng-app> <span>{{f ...

  2. Python黑帽编程 3.4 跨越VLAN

    Python黑帽编程 3.4 跨域VLAN VLAN(Virtual Local Area Network),是基于以太网交互技术构建的虚拟网络,既可以将同一物理网络划分成多个VALN,也可以跨越物理 ...

  3. 来,一起让我们越来越懒,面向CSS、JS未来编程。(9.28已更新)

    2016.10.29更新 本文存在大量的错误,仅供参考. 不知不觉在前端领域马上一个年头就要过去了,然而再看看自己的代码,果然够烂,那么为什么代码一直没有用面向对象的思维去写CSS呢?首先有两点:一点 ...

  4. 【WCF】基于WCF的在线升级

    一.前言       前不久因公司产品需要完成了在线升级功能,因为编程技术不精,不敢冒然采用Socket方法实现在线升级,所以使用比较方便稳妥的WCF方式 如果考虑并发能力的话还是Socket> ...

  5. JavaWeb_day01_HTTP_Servlet

    本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! JavaWeb_day01 HTTP协议 HTTP(H ...

  6. 随机数(random)

    需求 Random rd=new Random(); 需要十以内的随机数  (0---10) System.out.println((int)((rd.nextDouble()*100)/10)); ...

  7. Mac 热键大全

    屏幕捕捉快捷键动作............................保存到............-快捷键 全屏捕捉........................桌面(.PDF文件)..... ...

  8. 应用SuperIO(SIO)和开源跨平台物联网框架ServerSuperIO(SSIO)构建系统的整体方案

    SSIO的更新 在SSIO上增加了UDP通讯方式,可以到Github上下载源代码.在原来的项目中,远端的设备与中心站的数据交互并没有使用过UDP方式.这种短连接的通讯链路,不容易维护,主要体现在:(1 ...

  9. HttpClient调用webApi时注意的小问题

    HttpClient client = new HttpClient(); client.BaseAddress = new Uri(thisUrl); client.GetAsync("a ...

  10. LinqToXml (一) Create Xml file By Dom /Linq

    目前,在xml 应用编程领域比较流行的开发模型是W3C 提供的DOM(文档对象模型),在.net Framework 通过命名空间 System.Xml 对该技术提供了支持.随着Linq to XMl ...