博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[LeetCode] Russian Doll Envelopes 俄罗斯娃娃信封
阅读量:6223 次
发布时间:2019-06-21

本文共 3124 字,大约阅读时间需要 10 分钟。

 

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]).

 

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

 

解法一:

class Solution {public:    int maxEnvelopes(vector
>& envelopes) { int res = 0, n = envelopes.size(); vector
dp(n, 1); sort(envelopes.begin(), envelopes.end()); 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); } } res = max(res, dp[i]); } return res; }};

 

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

 

解法二:

class Solution {public:    int maxEnvelopes(vector
>& envelopes) { vector
dp; sort(envelopes.begin(), envelopes.end(), [](const pair
&a, const pair
&b){ if (a.first == b.first) return a.second > b.second; return a.first < b.first; }); for (int i = 0; i < envelopes.size(); ++i) { int left = 0, right = dp.size(), t= envelopes[i].second; while (left < right) { int mid = left + (right - left) / 2; if (dp[mid] < t) left = mid + 1; 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
>& envelopes) { vector
dp; sort(envelopes.begin(), envelopes.end(), [](const pair
&a, const pair
&b){ if (a.first == b.first) return a.second > b.second; return a.first < b.first; }); for (int i = 0; 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>也加入,再找最长序列。

 

类似题目:

 

参考资料:

 

转载地址:http://ysrja.baihongyu.com/

你可能感兴趣的文章
beanstalk源码剖析——概述
查看>>
[转] socket异步编程--libevent的使用
查看>>
linux下安装mysql详细步骤
查看>>
ASP.NET根据URL生成网页缩略图示例程序(C#语言)
查看>>
Core Animation
查看>>
linux----别名
查看>>
struts2拦截器demo
查看>>
go基本操作
查看>>
linux 安装jdk
查看>>
Kotlin入门(17)等式判断的情况
查看>>
Django rest_framework配合django_filter使用
查看>>
Windows下安装Python模块时环境配置
查看>>
Delphi 发展历史
查看>>
sharepoint2010 treeview实现
查看>>
转:为什么Maven Update Project JDK变回1.5
查看>>
航电 Problem 2044一直小蜜蜂
查看>>
luoguP1357 花园
查看>>
正则表达式
查看>>
运用<body>属性,渲染页面效果
查看>>
作业:实现简单的shell sed替换功能和修改haproxy配置文件
查看>>