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. u-boot源码分析之C语言段

    题外话: 最近一直在学习u-boot的源代码,从代码量到代码风格,都让我认识到什么才是真正的程序.以往我所学到的C语言知识和u-boot的源代码相比,实在不值一提.说到底,机器都是0和1控制的.感觉这 ...

  2. MongoDB安装使用

    标签: MongoDB 参考链接:Windows上安装MongoDB教程 1. 官方下载 MongoDB提供了可用于32位和64位系统的预编译二进制包,你可以从MongoDB官网下载安装,MongoD ...

  3. expect基本使用方法

    参考: http://www.cnblogs.com/lzrabbit/p/4298794.html expect是linux系统中可以和子进程进行交互的一个命令,使用它可以做一些自动化工作.pyth ...

  4. Python 基础之四初识Python数据类型

    数字 Int,整型 Float,浮点型 Long,长整型 布尔 字符串 列表 元组 字典 1.数字 INT(整型) 在32位系统上,整数的位数为32位,取值范围为-2**31~2**31-1,即-21 ...

  5. 解决 Tomcat Server in Eclipse unable to start within 45 seconds 不能启动的问题

    1.在 Eclipse 下方  Servers TAB页,双击 "Tomcat 7.0 at localhost": 2.在右上角处点开 Timeouts 的设定,修改Start( ...

  6. Hibernate全套增删改查+分页

    1.创建一个web工程 2.导入jar包 3.创建Student表 4.创建实体类 package com.entity; public class Student { private Integer ...

  7. Easyui dialog中嵌入iframe

    如果easyui dialog的地址属性用href超链接,easyui 不会加载整个url页面,只会截取url目标页的body体间的html, 如果想加载把其他页面 加载进dialog的iframe中 ...

  8. 浅析匿名函数、lambda表达式、闭包(closure)区别与作用

    浅析匿名函数.lambda表达式.闭包(closure)区别与作用 所有的主流编程语言都对函数式编程有支持,比如c++11.python和java中有lambda表达式.lua和JavaScript中 ...

  9. android:布局、绘制、内存泄露、响应速度、listview和bitmap、线程优化以及一些优化的建议!

    1.布局优化 首先删除布局中无用的控件和层级,其次有选择地使用性能较低的viewgroup,比如布局中既可以使用RelativeLayout和LinearLayout,那我们就采用LinearLayo ...

  10. Android GZIP压缩IO流,优化APP数据传输(一)

    我是小搬运工,今天讲解流的压缩传输 在我们安卓开发中,通常伴随着大量的数据传输,在此,楼主给出一个简单的压缩流的数据进行操作. public void GZIPCpf(String path) { / ...