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];
    }
};
相关推荐
无限码力20 分钟前
阿里算法岗 0530笔试真题 - 多约束条件下的元素匹配统计
算法·阿里笔试真题·阿里机试真题·阿里算法岗笔试
lqqjuly28 分钟前
MLA — 多头潜在注意力深度解析
深度学习·神经网络·算法
吴可可1231 小时前
SolidWorks草图转三维DWG技巧
算法
redaijufeng1 小时前
C++雾中风景7:闭包
c++·算法·风景
小欣加油2 小时前
leetcode287寻找重复数
数据结构·c++·算法·leetcode
尽兴-2 小时前
2.1 向量基础:Embedding、余弦相似度、欧氏距离、向量检索
算法·embedding·欧氏距离·向量检索·余弦相似度
Black蜡笔小新3 小时前
自动化AI算法训练服务器DLTM训推一体工作站赋能多行业智能化升级
人工智能·算法·自动化
怪兽学LLM3 小时前
LeetCode 438 找到字符串中所有字母异位词(Python 固定滑动窗口+字符计数解法)
python·算法·leetcode
满怀冰雪3 小时前
第04篇-双指针算法-从有序数组到回文判断的高频解法
java·算法