「这是我参与2022首次更文挑战的第37天,活动详情查看:2022首次更文挑战」
题目
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例1
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置 最大值
--------------- -----
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7
复制代码
示例2
输入: nums = [1], k = 1
输出: [1]
复制代码
题解
暴力枚举
通过枚举整个数组 ,再枚举寻找数组K长度最大值 ,找出其中的最大值,时间复杂度 有超时风险,所以需要想别的办法优化。
窗口队列
枚举整个数组 的花费是必不可少的,现在就是如何优化在窗口中寻找最大值;有没有可能在枚举的时候计算出最大值?
分析一下数据
窗口 | 数组 | 最大值 |
---|---|---|
窗口 1 | 3 | |
窗口 2 | 3 | |
窗口 3 | 5 | |
窗口 4 | 5 | |
窗口 5 | 6 | |
窗口 6 | 7 |
难点1
如何知道当前最大值需要移出【窗口】。
可不可以这样,记录最大值在原数组中的下标;并将下标存放到队列 中。
枚举过程中如果 stack[0] ; 需要将 首位移出窗口
通过枚举过程中维护 队列来快速获取【窗口】最大值 ;
难点2
如果最大值移出 队列,如何保证 是当前队列的最大值?
可以这样,在维护 队列时,将当前值 与 比较
- 如果
将
删除,继续比较
与
,直到 stack[stack.length-1] >=
;将当前值
中的
i
放入 队列 - 如果
;放弃
i
- 最后在 [k,nums.length] 区间,将 存放到结果数组中
- 返回结果数据
根据上述思路编辑代码如下:
var maxSlidingWindow = function (nums, k) {
if (k === 1) return nums;
const len = nums.length;
const stack = [];
let result = [];
for (let i = 0; i < len; i++) {
if (i - stack[0] >= k) stack.shift();
while (nums[stack[stack.length - 1]] <= nums[i]) {
stack.pop();
}
stack.push(i);
if (i >= k - 1) {
result.push(nums[stack[0]]);
}
}
return result;
};
复制代码
结语
作者水平有限,如有不足欢迎指正;任何意见和建议欢迎评论区浏览讨论