• Leetcode 2407. Longest Increasing Subsequence II


    Leetcode 2407. Longest Increasing Subsequence II

    You are given an integer array nums and an integer k.

    Find the longest subsequence of nums that meets the following requirements:>

    1. The subsequence is strictly increasing and
    2. The difference between adjacent elements in the subsequence is at most k.
    
    • 1
    • 2

    Return the length of the longest subsequence that meets the requirements.

    A subsequence is an array that can be derived from another array by deleting some or no > > elements without changing the order of the remaining elements.

    假设我们用一个数组 dp [ ] \text{dp}[] dp[]来存储以当前元素为结尾的最长递增子数列, 我们可以考虑对数组顺序循环,对每一个值 nums [ i ] \text{nums}[i] nums[i],满足constraint: j < i , nums [ j ] + k > = nums [ i ] j < i, \text{nums}[j] + k >= \text{nums}[i] j<i,nums[j]+k>=nums[i]的条件所有 j j j,求 max ⁡ dp [ j ] \max \text{dp}[j] maxdp[j]

    max ⁡ j < i dp [ j ] s . t . nums [ j ] + k > = nums [ i ] \max_{j < i}\text{dp}[j] \quad s.t. \text{nums}[j] + k >= \text{nums}[i] j<imaxdp[j]s.t.nums[j]+k>=nums[i]

    为了解这个问题,我们可以构造一个线段树 tree \text{tree} tree,其index可以表示 nums [ ] \text{nums}[] nums[]中的元素值的范围,对应value表示以该元素范围为结尾的最长递增子序列,那么在循环中我们只要查询 tree [ nums [ j ] − k : nums [ j ] − 1 ] \text{tree}[\text{nums}[j]-k : \text{nums}[j]-1] tree[nums[j]k:nums[j]1] 即可。这样的时间复杂度相当于扫一遍长度为 N N N的数组 nums \texttt{nums} nums,每次对最大数值范围为 M M M的线段树进行查询和更新操作,总复杂度为 O ( N log ⁡ M ) \mathcal{O}(N \log M) O(NlogM). 以下为code:

    class Solution {
    public:
    
        void update(vector& tree, int v, int tl, int tr, int pos, int new_val) {
            if (tl == tr) {
                tree[v] = max(new_val, tree[v]);
            } else {
                int tm = (tl + tr) / 2;
                if (pos <= tm)
                    update(tree, v*2, tl, tm, pos, new_val);
                else
                    update(tree, v*2+1, tm+1, tr, pos, new_val);
                tree[v] = max(tree[v*2], tree[v*2+1]);
            }
        }
    
        int get(vector& tree, int v, int tl, int tr, int l, int r) {
            if (l > r) return 0;
            if (tl == l && tr == r) return tree[v];
    
            int tm = (tl + tr) / 2;
            return max(
                get(tree, v*2,   tl,   tm, l, min(tm, r)),
                get(tree, v*2+1, tm+1, tr, max(tm+1, l), r)
            );
        }
    
        int lengthOfLIS(vector& nums, int k) {
            vector tree(400000, 0);
            for (auto it = nums.begin(); it != nums.end(); ++it) {
                int sub = get(tree, 1, 1, 100000, max(1,(*it)-k), (*it)-1);
                update(tree, 1, 1, 100000, *it, sub+1);
            }
            return tree[1];
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
  • 相关阅读:
    算法---滑动窗口练习-5(将x减到0的最小操作数)
    【Git进阶】基于文件(夹)拆分大PR
    智能垃圾设备监测系统
    【C++杂货铺】set 和 map 使用总结
    我的世界优化模组推荐:1.19.2 Fabric优化模组
    搞深度学习如何快速读懂开源代码?
    [附源码]SSM计算机毕业设计校园征兵及退役复原管理系统JAVA
    多媒体技术1-颜色在计算机中的表示
    SSH基于SSH的HR人事管理系统
    基于MATLAB的图像条形码识别系统(matlab毕毕业设计2)
  • 原文地址:https://blog.csdn.net/Faldict/article/details/134486742