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

最长上升子序列(三)

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 陕西

相关推荐

评论
1
收藏
分享

创作者周榜

更多
正在热议
更多
# 一张图晒出你司的标语 #
4378次浏览 77人参与
# AI面会问哪些问题? #
28219次浏览 565人参与
# 米连集团26产品管培生项目 #
13397次浏览 285人参与
# 你的实习产出是真实的还是包装的? #
20395次浏览 343人参与
# 找AI工作可以去哪些公司? #
9351次浏览 247人参与
# 春招至今,你的战绩如何? #
66175次浏览 584人参与
# 开放七大实习专项,百度暑期实习值得冲吗 #
15381次浏览 223人参与
# 从事AI岗需要掌握哪些技术栈? #
9172次浏览 321人参与
# 中国电信笔试 #
32068次浏览 295人参与
# 你做过最难的笔试是哪家公司 #
34279次浏览 245人参与
# 投递几十家公司,到现在0offer,大家都一样吗 #
340960次浏览 2175人参与
# 哪些公司真双非友好? #
69694次浏览 289人参与
# 阿里笔试 #
179001次浏览 1318人参与
# 机械人避雷的岗位/公司 #
62708次浏览 393人参与
# 小马智行求职进展汇总 #
25139次浏览 80人参与
# 第一份工作一定要去大厂吗 #
14875次浏览 122人参与
# 金三银四,你的春招进行到哪个阶段了? #
22226次浏览 284人参与
# 担心入职之后被发现很菜怎么办 #
291382次浏览 1210人参与
# 为了减少AI幻觉,你注入过哪些设定? #
26274次浏览 310人参与
# 应届生第一份工资要多少合适 #
20694次浏览 86人参与
# HR最不可信的一句话是__ #
6346次浏览 114人参与
# 沪漂/北漂你觉得哪个更苦? #
10029次浏览 194人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务