题解 | #最长上升子序列(三)#

最长上升子序列(三)

https://www.nowcoder.com/practice/9cf027bf54714ad889d4f30ff0ae5481

C++, 贪心 + 二分查找

设置一个记录上升子序列状态的二维dp[n + 1][ ];

vector<vector> dp_str(n + 1, vector ());
第一维下标代表当前长度,其第二维代表最长子序列

贪心思想:若想让子序列长度更长,则应确保每次增加新元素的幅度尽可能的小,“小步多走”;

从头遍历数组,寻找 ==以当前元素为最后元素== 的上升子序列;

  1. 若 当前元素 > 当前最长子序列的最后一个元素,则添加并更新最长子序列;
  2. 若 当前元素 <= 当前最长子序列的最后一个元素, 则其可以替代当前最长子序列中间的某一个元素,为后面的上升序列做铺垫
    • 二分查找 在当前最长子序列中 查找 【第一个小于当前元素的元素位置pos】,并在其后替换更新
    • 按字典顺序大小 比较 【新取得的子序列temp 】 与 【已有的同长度的子序列dp_str[pos + 1]】 哪个更小,保留字典序列小的;
class Solution {
public:
    /**
     * retrun the longest increasing subsequence
     * @param arr int整型vector the array
     * @return int整型vector
     */
    vector<int> LIS(vector<int>& arr) {
        // write code here
        int n = arr.size();
        // 第一维下标代表当前长度,其第二维代表最长子序列
        vector<vector<int>> dp_str(n + 1, vector<int> ());
        // 初始化第一个长度为1的开始子序列
        int len = 1; 
        dp_str[len].emplace_back(arr[0]);

        for (int i = 1; i < n; ++i) {
            // 若 当前元素 > 当前最长子序列的最后一个元素,则添加并更新最长子序列
            if (arr[i] > dp_str[len].back()) {
                ++len;
                dp_str[len] = dp_str[len - 1];
                dp_str[len].emplace_back(arr[i]);
            }
            // 若 当前元素 < 当前最长子序列的最后一个元素, 则其可以替代最长子序列中间的某一个元素
            else {
                // 二分查找 在当前最长子序列中 查找 第一个小于当前元素的元素位置,并更新
                int l = 1, r = len, pos = 0;
                while (l <= r) {
                    int mid = l + ((r - l) >> 1);
                    if (dp_str[mid].back() < arr[i]) {
                        l = mid + 1;
                        pos = mid;
                    }
                    else {
                        r = mid - 1;
                    }
                }
                // temp 为 若成功替换后,新的以arr[i]结尾,长度为pos + 1 的子序列
                vector<int> temp = dp_str[pos];
                temp.emplace_back(arr[i]);
                // 与以及存在的 同长度的 子序列 按字典大小比较,若新的更小,则更新
                if (temp < dp_str[pos + 1]) {
                    dp_str[pos + 1] = temp;
                } 
//                 // 否则, 只更新最后一个元素
//                 else {
//                     dp_str[pos + 1].back() = arr[i];
//                 }
            }
        }
        return dp_str[len];
    }
};
全部评论
行行有大神
1 回复 分享
发布于 2022-10-22 18:56 陕西

相关推荐

NBA球星伦纳德:jd是这样的,工作连拧螺丝都算不上
点赞 评论 收藏
分享
03-24 13:24
已编辑
江西农业大学 后端工程师
最近或许大家都听说xxxx厂裁员,无论前端,后端,大数据,测试,运维,人人可危,&nbsp;“前端死了,后端也死了,JAVA崩盘了,你们这群搞大模型的真是码奸”这次AI真的会让我们无路可走吗????????太阳底下已经没有新鲜事了旧的生产力的消失,必然有新的生产力诞生马车夫消失&nbsp;→&nbsp;汽车司机、修车工、石油工业诞生,从业人数是马车夫的百倍手工纺织女工消失&nbsp;→&nbsp;纺织机械工程师、面料设计师诞生,纺织品产量提升百倍2007年苹果开放&nbsp;App&nbsp;Store,&quot;移动端开发者&quot;这个职业压根不存在。八年后,全球应用经济规模突破&nbsp;1000亿美元,凭空诞生了数百万开发者岗位。每一次&quot;这次真的完了...
二十岁的编程男神王大...:那这个时代是什么时代呢? 是全员agent的时代,是前端+AI,后端+AI的时代,AI已经融入了项目生命周期的的每一个角落,那我最近在做的东西举例,检查BUG时,我们会用codex,CC等工具的skill去check,效果好还能直接fix,测试的时候,apifox等工具已经有了AI落地的改造,CI/CD阶段,我们会根据hook去跑AI check脚本,就连不少中间件,也迎来了AI落地的改造,(AI网关,AI在MQ中的运用),都可以去了解下 另外记着,这些东西不是意义,工作只是谋生的一个手段,ai是让开发提效了,但是呢,原先一周的工作流程压缩到了两天内,同时低级的都裁员了,只有高级的去维护,你看似写的大义凛然,或许那天你也会成为你文章里面拒绝往前走的人,你才大二,面对技术有热情是对的
AI求职实录
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务