持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天,点击查看活动详情
题目(Sliding Window Maximum)
链接:leetcode-cn.com/problems/sl… 解决数:2606 通过率:50% 标签:队列 数组 滑动窗口 单调队列 堆(优先队列) 相关公司:amazon google facebook 给你一个整数数组 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]
提示:
1 <= nums.length <= 105 -104 <= nums[i] <= 104 1 <= k <= nums.length
思路
- 核心思路:维护一个单调队列,队头元素到队尾元素依次递减,然后最大值就是队列中的第一个元素
- 合法性判断:滑动窗口外的元素删掉
- 维护单调队列:如果新加进来的数大于等于队尾元素,则依次将队尾元素删除,始终维护队头元素是最大值
- 当满足滑动窗口区间范围时,将队头元素推入结果数组中。
代码
/**
* @param {number[]} nums
* @param {number} k
* @return {number[]}
*/
var maxSlidingWindow = function(nums, k) {
const deque=[]; //存放单调队列的下标
const result=[];
for(let i=0;i=k) deque.shift(); //在滑动窗口之外的直接从队头删掉
while(nums[deque[deque.length-1]]<=nums[i]){
deque.pop(); //如果新加进来的数比单调队列中原来的数都要大,则直接弹出队列中的其他数
}
deque.push(i);
//数组下标从0开始,k=3时 ,下标为0,1,2的数组元素构成一个滑动窗口,所以条件为i>=k-1就可以将答案存入res中
if(i>=k-1) {
result.push(nums[deque[0]]);
}
}
return result;
};