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.

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 numsi,满足constraint: j < i , nums j + k > = nums i j < i, \text{nums}j + k >= \text{nums}i j<i,numsj+k>=numsi的条件所有 j j j,求 max ⁡ dp j \max \text{dp}j maxdpj

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<imaxdpjs.t.numsj+k>=numsi

为了解这个问题,我们可以构造一个线段树 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] treenums\[j−k:numsj−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<int>& 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<int>& 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<int>& nums, int k) {
        vector<int> 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];
    }
};
相关推荐
atunet8 分钟前
关于图算法中的连通分量检测与最小割问题7
算法
心运软件35 分钟前
银行客户流失预测(Python 完整实战)
算法
邪神与厨二病39 分钟前
牛客周赛 Round 153
python·算法
qizayaoshuap3 小时前
# ❌ 井字棋 — 鸿蒙ArkTS Minimax AI算法与博弈系统设计
人工智能·算法·华为·harmonyos
皓月斯语3 小时前
B3842 [GESP202306 三级] 春游 题解
数据结构·c++·算法·题解
atunet3 小时前
树状结构在查询优化中的作用与实现细节7
算法
徐凤年_4 小时前
rog_map参数理解
算法
春日见4 小时前
算法与数据结构----哈希表
数据结构·人工智能·算法·机器学习·自动驾驶·哈希算法·散列表
叩码以求索4 小时前
统计按位或能得到最大值的子集数目(一)
数据结构·算法
tachibana25 小时前
hot100 数组中的第K个最大元素(215)
java·数据结构·算法·leetcode