Leetcode 俄罗斯套娃信封问题

对于我这种没有DP思维的想这种问题实在太难,看了下题解再去补了下LCS和LIS,发现还是不太会。最主要是二维的东西,一个被另一个所牵制。

解法:很直观的想法就是利用pair的性质把这个数组排个序,此时第一个已经是递增的了,然后按照第二个递增来做。但是这样并没有办法解决第一个牵制的问题,就比如1 1,1 2, 1 3,如果只看到第二维1 2 3而没有看到第一维1 1 1的相同性,就没办法得到正确的答案。此时怎么办呢?

  上面的问题在于在first相同的情况下,却仍然存在递增的情况,使得答案不准确。如果我们把第二维按照降序排列,也就是变成3 3, 3 2, 3 1,这样看着3 2 1,就可以很好判断出最长递增序列长度为1了。但是如果有个1 1,那3 1就会顶掉1 1,此时就会是1 3 -> 1 2 -> 1 2,第二次的1 2的1是由3 1的1得到来的。由于有1 1的存在,所以在最前面创建了一个位置,后面即使顶掉也无所谓,你可以认为就仍在是1 1,也可以认为是3 1,反正后面的firts肯定比3要大。

bool cmp(pair<int, int> a, pair<int, int> b) {
    if(a.first != b.first)
        return a.first < b.first;
    return a.second > b.second;
}

class Solution {
public:
    int maxEnvelopes(vector<pair<int, int>>& envelopes) {
        int n = envelopes.size();
        if(!n)
            return 0;
        sort(envelopes.begin(), envelopes.end(), cmp);
        vector <int> dp, dp_2;
        dp.push_back(envelopes[0].second);
        dp_2.push_back(envelopes[0].first);
        for(int i = 1; i < n; ++i) {
            int p = lower_bound(dp.begin(), dp.end(), envelopes[i].second) - dp.begin();
            if(p == dp.size()) {
                dp.push_back(envelopes[i].second);
                dp_2.push_back(envelopes[i].first);
            } else {
                dp[p] = envelopes[i].second;
                dp_2[p] = envelopes[i].first;
            }
        }
        return dp.size();
    }
};

猜你喜欢

转载自www.cnblogs.com/llzhh/p/10191162.html