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] 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<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];
    }
};
相关推荐
塔中妖6 小时前
【华为OD】分割数组的最大差值
数据结构·算法·华为od
weixin_307779136 小时前
最小曲面问题的欧拉-拉格朗日方程 / 曲面极值问题的变分法推导
算法
RTC老炮7 小时前
webrtc弱网-AlrDetector类源码分析与算法原理
服务器·网络·算法·php·webrtc
孤廖7 小时前
【算法磨剑:用 C++ 思考的艺术・Dijkstra 实战】弱化版 vs 标准版模板,洛谷 P3371/P4779 双题精讲
java·开发语言·c++·程序人生·算法·贪心算法·启发式算法
sali-tec7 小时前
C# 基于halcon的视觉工作流-章33-矩状测量
开发语言·人工智能·算法·计算机视觉·c#
songx_997 小时前
leetcode29( 有效的括号)
java·数据结构·算法·leetcode
于樱花森上飞舞7 小时前
【java】常见排序算法详解
java·算法·排序算法
GawynKing8 小时前
图论3 图的遍历
算法·深度优先
东方芷兰9 小时前
Leetcode 刷题记录 21 —— 技巧
java·算法·leetcode·职场和发展·github·idea
kyle~9 小时前
排序---选择排序(Selection Sort)
java·算法·排序算法