LeetCode 354 俄罗斯套娃信封问题

这道题给出的是信封的长度和宽度,只有一个信封长度和宽度都比一个信封小时,才能将这个小的信封放入大的信封里,问最多可以嵌套放多少个信封,信封不可以旋转。这道题和之前做过的一个嵌套矩形很像,不过那个可以旋转,用DAG上的动态规划就可以做,这道题我开始也是用同样的方法,但是不行,时间复杂度O(n²),会超时。后来看了解题思路才突然想到方法,首先将信封排序,先按w升序排,然后按h降序排,这样的目的是能保证只要后面的信封h比前面大,就能把前面的信封放到后面的信封中,而且防止同w的信封嵌套。维护一个数组保存长度最大为len时的信封宽度,做到这里其实就是最长上升子序列问题了。最长上升子序列的做法可以看这里————最长上升子自序列。这种方法的时间复杂度为O(nlogn),可以通过。

class Solution {
public:
    static bool cmp (vector<int> a,vector<int> b)
    {
        return a[0]<b[0]||(a[0]==b[0]&&a[1]>b[1]);
    }
    int maxEnvelopes(vector<vector<int>>& envelopes) {
        int sz=envelopes.size();
        int dp[sz+1],len=0;
        sort(envelopes.begin(),envelopes.end(),cmp);
        dp[0]=0;
        for(int i=0;i<sz;i++)
        {
            if(envelopes[i][1]>dp[len])
            {
                len++;
                dp[len]=envelopes[i][1];
            }
            else
            {
                int l=0,r=len,mid;
                while(l<=r)
                {
                    mid=(l+r)/2;
                    if(dp[mid]<envelopes[i][1])
                    {
                        l=mid+1;
                    }
                    else
                    {
                        r=mid-1;
                    }
                }
                dp[l]=envelopes[i][1];
            }
        }
        return len;
    }
};
posted @ 2020-06-09 11:29  South1999  阅读(116)  评论(0编辑  收藏  举报