LeetCode|1438. 绝对差不超过限制的最长连续子数组(day10)

作者:MJ昊

博客:掘金CSDN

公众号:程序猿的编程之路

今天是 昊 的算法之路第10天,今天分享的是LeetCode第1438题绝对差不超过限制的最长连续子数组的解题思路。这道题目难度为中等,通过滑动窗口与双端队列可以高效解决问题。

题目描述简要回顾

题目要求我们找到一个连续子数组,使得该子数组中最大值与最小值的绝对差不超过给定的 limit,并返回满足条件的最长子数组的长度。

解题思路

本题可以通过滑动窗口和双端队列来高效解决。

  • 使用两个双端队列 queMaxqueMin 分别存储当前窗口内的最大值和最小值。
  • 我们将右边界 right 向右移动,不断扩大窗口。
  • 每次移动 right 后,分别维护 queMaxqueMin,确保 queMax 中的数值是递减的,queMin 中的数值是递增的,以快速找到当前窗口的最大值和最小值。
  • queMax 的最大值与 queMin 的最小值之差大于 limit 时,开始移动左边界 left,直到差值回到符合要求的范围。
  • 每次移动后,更新最大长度 ret

代码实现:

var longestSubarray = function(nums, limit) {
    const queMax = [];
    const queMin = [];
    const n = nums.length;
    let left = 0, right = 0;
    let ret = 0;
    while (right < n) {
        // 维护 queMax 使其为递减队列
        while (queMax.length && queMax[queMax.length - 1] < nums[right]) {
            queMax.pop();
        }
        // 维护 queMin 使其为递增队列
        while (queMin.length && queMin[queMin.length - 1] > nums[right]) {
            queMin.pop();
        }
        queMax.push(nums[right]);
        queMin.push(nums[right]);
        // 当窗口内最大值与最小值的差值超过 limit 时,移动左边界
        while (queMax.length && queMin.length && queMax[0] - queMin[0] > limit) {
            if (nums[left] === queMin[0]) {
                queMin.shift();
            }
            if (nums[left] === queMax[0]) {
                queMax.shift();
            }
            left++;
        }
        // 更新最大长度
        ret = Math.max(ret, right - left + 1);
        right++;
    }
    return ret;
};

复杂度分析

  • 时间复杂度:O(n),其中 n 是数组 nums 的长度。每个元素最多被加入和移除队列一次,因此时间复杂度是线性的。
  • 空间复杂度:O(n),双端队列的空间最多为数组的长度。

总结

这道题通过滑动窗口结合双端队列有效解决了寻找最长符合条件的子数组的问题,滑动窗口技巧帮助我们在线性时间内找到符合要求的子数组,保证了算法的高效性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值