您的位置:首页 > 运维架构

leetcode Russian Doll Envelopes

2016-07-18 20:36 423 查看
题目要求用大信封装小信封,问最多可以这样嵌套多少个。

最简单的做法就是动态规划,01背包问题,把数组排序,先按第一个元素排序,再按第二个元素排序。dp[i]表示以i作为最大信封,0-i个信封,最多装多少个。问题没有后续性,时间复杂度O(n^2)

然而如果我们对第二个元素排序时按从大到小排序,这时候有个神奇的东西诞生了。

问题等价于求LIS(最长上升子序列的长度),倒序第二个元素是为了排除第一个元素相同,第二个元素算了几个进去。

于是我们用单调栈就可以解决啦,dp[i]表示长度为i+1的子序列,i这个元素最小是多少。注意单调栈中的结果不一定是最后最长长度的解哦。

bool cmp( 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;

}

class Solution {

public:
int maxEnvelopes(vector<pair<int, int>>& envelopes) {
int n = envelopes.size();
if(n==0)return 0;
vector<int> dp(n,0);
int top = 0;
sort(envelopes.begin(), envelopes.end(), cmp );
for( auto tInfo: envelopes )
{
if( top == 0 )
{
dp[top++] = tInfo.second;
continue;
}

if( dp[top - 1] < tInfo.second )
{
dp[top++] =tInfo.second;
continue;
}

int low = 0, high = top - 1;
while( low < high )
{
int mid = low + ((high - low) >> 1);
if( dp[mid] < tInfo.second )low = mid + 1;
else
{
high = mid;
}
}
dp[low] = tInfo.second;
}
return top;
}

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: