算法题解-滑动窗口最大值

128 阅读3分钟

题目

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

输入: nums = [1,3,-1,-3,5,3,6,7], k = 3
输出: [3,3,5,5,6,7]

题解

第一种

我们先在函数中定义六个变量,length变量表示数组的长度减一,right变量和left变量分别表示窗口的右边界和左边界,maxValue变量表示当前窗口中的最大值,ret变量是最终返回的数组,cnt变量表示当前窗口中元素的个数,然后我们使用循环来遍历整个数组,在每个循环中,先用另一个循环来将窗口中的元素个数增加到k,我们每次在循环中将maxValue更新为当前窗口中的最大值,同时将right指针右移,当窗口中的元素个数达到k时,将maxValue加入到ret数组中,并判断左边界元素是否等于maxValue,如果满足条件则表明maxValue即将离开窗口,需要重新寻找窗口中的最大值,此时将maxValue重新赋值为最小安全整数,将right指针移动到左边界的位置,同时将cnt重新赋值为1,如果左边界元素不等于maxValue,则将cnt减1,最后我们将ret数组返回即可

var maxSlidingWindow = function(nums, k) {
    let length = nums.length - 1
    let right = 0
    let left = 0
    let maxValue = Number.MIN_SAFE_INTEGER
    let ret = []
    let cnt = 1
    while (right <= length) {
        while (cnt <= k) {
            maxValue = Math.max(maxValue, nums[right++])
            cnt++
        }
        ret.push(maxValue)
        if (nums[left++] === maxValue && right <= length) {
            maxValue = Number.MIN_SAFE_INTEGER
            right = left
            cnt = 1
        } else {
            cnt--
        }
    }
    return ret
};

第二种

我们这里先声明一个n常量记录nums参数的长度和一个空数组q常量,用于存储当前窗口中的元素下标,然后我们使用循环处理前k个元素,每次将当前元素的下标i加入到q数组中,并保持q数组中的元素下标对应的元素是单调递减的,如果当前元素大于等于q数组中最后一个元素对应的元素,就将最后一个元素从q数组中删除,直到当前元素小于q数组中最后一个元素对应的元素,再将当前元素的下标i加入到q数组中,接下来我们使用循环遍历整个数组,从第k个元素开始处理,在每个循环中我们将当前元素的下标i加入到q数组中,并保持q数组中的元素下标对应的元素是单调递减的,如果q数组中的第一个元素对应的下标小于等于i-k,则说明这个元素已经离开了当前窗口,我们需要将其从q数组中删除,最后我们将q数组中的第一个元素对应的元素加入到ans数组中,最后将ans数组返回即可

var maxSlidingWindow = function(nums, k) {
    const n = nums.length;
    const q = [];
    for (let i = 0; i < k; i++) {
        while (q.length && nums[i] >= nums[q[q.length - 1]]) {
            q.pop();
        }
        q.push(i);
    }
    const ans = [nums[q[0]]];
    for (let i = k; i < n; i++) {
        while (q.length && nums[i] >= nums[q[q.length - 1]]) {
            q.pop();
        }
        q.push(i);
        while (q[0] <= i - k) {
            q.shift();
        }
        ans.push(nums[q[0]]);
    }
    return ans;
};

坚持努力,无惧未来!