239. 滑动窗口最大值
- 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回滑动窗口中的最大值。
示例:
输入: nums = [1,3,-1,2,5,3,6,7], 和 k = 2
输出: [3, 3, 2, 5, 5, 6, 7]
解释:
滑动窗口的位置 最大值
--------------- -----
[1 3] -1 2 5 3 6 7 3
1 [3 -1] 2 5 3 6 7 3
1 3 [-1 2] 5 3 6 7 2
1 3 -1 [2 5] 3 6 7 5
1 3 -1 2 [5 3] 6 7 5
1 3 -1 2 5 [3 6] 7 6
1 3 -1 2 5 3 [6 7] 7
思路:双端队列
使用一个双端队列记录窗口滑动过程,注意:队列中放入的是索引
遍历nums:
- 将第一个元素放入队列
- 遍历之后的元素时,判断其与队列中前一个元素值的大小关系:
若大于前一个元素,则将前一个元素弹出,并继续向前判断,最终将其添加到队列
若小于前一个元素,则将其添加到队列中
以上操作的目的是,将当前窗口的最大元素放在队列的首端 - 为了保证队列中元素都为当前窗口的元素,在每次添加元素索引之后,还需做一步判断:
判断当前索引 - 队首索引 是否等于 窗口宽度k
若相等,说明队首元素的索引已经超出当前窗口,将其弹出 - 将队首元素放入结果集
- 返回结果集中k-1之后的元素,因为k-1前不是有效的滑动窗口
代码实现:
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
deque = []
ret = []
for i in range(len(nums)):
while deque and nums[i] > nums[deque[-1]]:
deque.pop()
deque.append(i)
if i - deque[0] == k:
deque.pop(0)
ret.append(nums[deque[0]])
return ret[k-1:]