码迷,mamicode.com
首页 > 其他好文 > 详细

最长上升子序列

时间:2021-01-06 12:12:27      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:++i   ems   图解   pos   cto   ++   来源   商业   vector   

一步一步推导出官方最优解法,详细图解

上面这篇文章讲的很详细了。

300. 最长递增子序列

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        vector<int> minList;
        for(auto& i : nums){
            if(minList.empty() || i > minList.back()){
                minList.emplace_back(i);
            }else{
                *lower_bound(minList.begin(), minList.end(), i) = i;
            }
        }
        return minList.size();
    }
};

673. 最长递增子序列的个数

class Solution {
public:
    int findNumberOfLIS(vector<int>& nums) {
        vector<vector<int>> elms, ops;

        for(int v : nums) {
            int pos, paths = 1;

            /* 一、二分查找 “生长点”。 */
            if(elms.size() == 0 || v > elms.back().back()) {
                pos = elms.size();
            } else {
                pos = lower_bound(elms.begin(), elms.end(), v, [](vector<int> &a, const int &b){
                    return a.back() < b;
                }) - elms.begin();
            }

            /* 二、二分查找 “可以插入的最大尾数”。*/
            if(pos > 0) {
                int pre = pos - 1;
                int p2 = upper_bound(elms[pre].begin(), elms[pre].end(), v, greater<int>()) - elms[pre].begin();
                paths = ops[pre].back() - (p2? ops[pre][p2-1] : 0);
            }

            /* 三、计算以元素 v 结尾的, 长度为 pos + 1 的上升子序列个数,并累加前缀和。*/
            if(pos == elms.size()) {
                elms.push_back({v}), ops.push_back({paths});
            } else {
                elms[pos].push_back(v);
                ops[pos].push_back(paths + ops[pos].back());
            }
        }

        return ops.size()? ops.back().back() : 0;
    }
};

作者:newhar
链接:https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/solution/yi-bu-yi-bu-tui-dao-chu-zui-you-jie-fa-2-zui-chang/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

354. 俄罗斯套娃信封问题

class Solution {
public:
    int maxEnvelopes(vector<vector<int>>& envelopes) {
        int n = envelopes.size();
        if(n == 0) return 0;
        sort(envelopes.begin(), envelopes.end(), [](auto& a, auto& b){
            return a[0] < b[0] || (a[0] == b[0] && a[1] > b[1]);
        });

        vector<int>dp;
        dp.push_back(envelopes[0][1]);
        for(int i=1; i<n; ++i){
            if(envelopes[i][1] > dp.back()){
                dp.emplace_back(envelopes[i][1]);
            }else{
                *lower_bound(dp.begin(), dp.end(), envelopes[i][1]) = envelopes[i][1];
            }
        }
        return dp.size();
    }
};

最长上升子序列

标签:++i   ems   图解   pos   cto   ++   来源   商业   vector   

原文地址:https://www.cnblogs.com/miyanyan/p/14225526.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!