1. 题目:
给你一个整数数组 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]
2. 我的代码:
import collections class Solution: def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]: # 排除特殊情况 if len(nums) == 1: return nums if k == 1: return nums q = collections.deque() result = [] # 第一个放进去 q.append(0) for i in range(1, len(nums)): while len(q): if nums[q[-1]] >= nums[i]:# 可以直接放进去 q.append(i) break else: # 不可以直接放进去 q.pop() if len(q) == 0: q.append(i) break # 保持大小 while q[-1] - q[0] + 1 > k: q.popleft() if i >= k - 1: result.append(nums[q[0]]) return result
利用双端队列,实现单调队列。每次放入元素都检查是否可以直接放入元素,通过反复和队尾元素对比,如果放入的元素比队尾元素小,则正常放入;如果比队尾元素大,则将队尾元素pop出去,再放入。为了保持单调递减的队列。
(如果剩下的队列为空了,就不再比较了,直接放入当前元素即可)
单调递减的队列的最大值必然是队列的队头元素。放入元素完毕后还需要通过反复删除队头元素来保持滑动窗口的大小。
在i >= k - 1
时开始统计结果。
最开始要排除特殊情况,就是nums的长度为0或者k为0的情况,这时原封不动返回nums即可。