题目
- 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。返回 滑动窗口中的最大值 。
法一、暴力枚举
- 遍历数组,获取每个窗口的子数组,找到当前窗口的最大值并加入结果数组
var maxSlidingWindow = function(nums, k) {
let res = [];
for (let i = 0; i <= nums.length - k; i++) {
// 获取当前窗口的子数组
let window = nums.slice(i, i + k);
// 找到当前窗口的最大值
let maxVal = Math.max(...window);
// 将最大值加入结果数组
res.push(maxVal);
}
return res;
};
法二、双端队列
- 思路:挨个遍历数组,用一个双端队列往对列右边加入,如果对列中存在比当前元素小的就左边弹出,如果超过了滑动窗口的范围也缩小左边 ,每到滑动窗口的大小时就将最大值(第一个元素)放进结果数组。
var maxSlidingWindow = function(nums, k) {
let res = [];
let deque = []; // 用于存储当前窗口内有用元素的索引
for (let i = 0; i < nums.length; i++) {
// 移除不在窗口内的元素:确保窗口大小不超过k
if (deque.length && deque[0] < i - k + 1) {
deque.shift();//删除数组第一个元素
}
// 移除小于当前元素的元素索引
while (deque.length && nums[deque[deque.length - 1]] < nums[i]) {
deque.pop();//删除数组的最后一位
}
// 将当前元素索引加入到 deque
deque.push(i);//向数组尾部添加
// 从第 k-1 个元素开始,添加当前窗口的最大值到结果数组
if (i >= k - 1) {
res.push(nums[deque[0]]);//最后的对列是单调的,第一个元素是最大的
}
}
return res;
};