美文网首页
Russian Doll Envelopes

Russian Doll Envelopes

作者: 我叫胆小我喜欢小心 | 来源:发表于2017-05-04 13:54 被阅读63次

    题目来源
    给一堆(width, height)的信封,大信封装小信封,问最多可以嵌套几个信封。实际上就是一个最长上升子序列问题,不过改成了二维的。
    我是先把width排序,然后求height的最长上升子序列,写的有点乱糟糟的,不过至少AC了,代码如下:

    class Solution {
    public:
        int maxEnvelopes(vector<pair<int, int>>& envelopes) {
        sort(envelopes.begin(), envelopes.end());
        vector<vector<int>> widths;
        int nums = envelopes.size();
        if (nums == 0)
            return 0;
        for (int i=0; i<nums; i++) {
            vector<int> width;
            width.push_back(envelopes[i].second);
            while (i+1 < nums && envelopes[i].first == envelopes[i+1].first) {
                width.push_back(envelopes[i+1].second);
                i++;
            }
            widths.push_back(width);
        }
        int widthNums = widths.size();
        vector<vector<int>> dp;
        vector<int> minWidth(widths[0].size(), 1);
        dp.push_back(minWidth);
        for (int i=1; i<widthNums; i++) {
            vector<int> maxEnveSoFar(widths[i].size(), 0);
            for (int j=0; j<widths[i].size(); j++) {
                int curHeight = widths[i][j];
                int curMax = 1;
                for (int k=0; k<i; k++) {
                    int l = 0, r = widths[k].size() - 1, mid = 0;
                    while (l <= r) {
                        mid = (l + r) / 2;
                        if (widths[k][mid] >= curHeight)
                            r = mid - 1;
                        else
                            l = mid + 1;
                    }
                    if (widths[k][0] >= curHeight)
                        continue;
                    else {
                        if (widths[k][mid] < curHeight)
                            curMax = max(curMax, dp[k][mid] + 1);
                        else
                            curMax = max(curMax, dp[k][mid-1] + 1);
                    }
                }
                maxEnveSoFar[j] = curMax;
            }
            dp.push_back(maxEnveSoFar);
        }
        int res = 0;
        for (auto item : dp) {
            for (auto j : item)
                res = max(res, j);
        }
        return res;
    }
    };
    

    看了下答案,然后再次感觉自己弱爆了,实际上只要按width升序,height降序,然后求height的最长上升子序列就可以了。
    代码如下:

    class Solution {
    public:
        static bool cmp_first(const pair<int, int>& i, const pair<int, int>& j)
        {
            if (i.first == j.first)
                return i.second > j.second;
            return i.first < j.first;
        }
    
        int maxEnvelopes(vector<pair<int, int>>& envelopes) {
            sort(envelopes.begin(), envelopes.end(), cmp_first);
            int nums = envelopes.size();
            vector<int> tails(nums, 0);
            int size = 0;
            for (int i=0; i<nums; i++) {
                int l = 0, r = size;
                while (l != r) {
                    int mid = (l + r) / 2;
                    if (tails[mid] >= envelopes[i].second)
                        r = mid;
                    else
                        l = mid + 1;
                }
                tails[l] = envelopes[i].second;
                if (l == size)
                    size++;
            }
            return size;
        }
    };
    

    相关文章

      网友评论

          本文标题:Russian Doll Envelopes

          本文链接:https://www.haomeiwen.com/subject/ppwrtxtx.html