携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情
滑动窗口最大值
给你一个整数数组
nums,有一个大小为k**的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的k个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。
链接: 239. 滑动窗口最大值
分析
根据题意,得出方法
- 大小为k的滑动窗口,从数组的最左侧移动到数组的最右侧。那么k中元素变化的行为能够想到与队列的行为类似,先进先出,因此可以使用队列来具体的描述滑动窗口的行为
- 每次滑动的时候,滑动窗口都会有一个最大值,根据示例可知,返回的结果为滑动窗口每次在数组滑动时,窗口内最大值的数组
优化
- 为了能更快的得到滑动窗口的最大值,队列记录最大值的数组下标,在遍历滑动窗口时,如果遍历当前数组下标为i的值,大于队列中最后入队的值,那最大值的下标是当前的,可以让之前下标出队后,当前坐标入队,如果小于,那就可以入队,此时队列的头部是滑动窗口最大值的数组下标
- 当然,如果窗口滑动之后,之前的队列头部需要及时出队,防止最大值计算错误
代码
/**
* @param {number[]} nums
* @param {number} k
* @return {number[]}
*/
var maxSlidingWindow = function(nums, k) {
let q = []
let ans = []
for(let i=0; i<k;i++) {
while(q.length && nums[i] > nums[q[q.length - 1]]) {
q.pop()
}
q.push(i)
}
ans.push(nums[q[0]])
for(let i=k; i<nums.length; 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
};
总结
- 当题目中需要求最值时,维护一种单调的数据结构是一种不错的选择
- 面对题目中描述的行为,可以熟练映射到特殊的数据结构,也能给解题带来很多的便利
- 今天也是有收获的一天