滑动窗口的最大值
Last updated
Last updated
问题简述
给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。
给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。
示例:
输入: 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
提示:
你可以假设 k 总是有效的,在输入数组不为空的情况下,1 ≤ k ≤ 输入数组的大小。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/hua-dong-chuang-kou-de-zui-da-zhi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
使用单调队列维护一个最大值序列,每次滑动窗口前,更新单调队列,使队首元素为下一个窗口中的最大值,详见参考链接或具体代码;
跟官方写法的区别:
官方的单调队列维护的是数组下标,通过判断下标位置来确定是否移除队首元素;因此可以使用严格单调队列;而下面的写法中使用值来判断是否移除队首,因此使用的是非严格单调队列(相关代码段:if q[0] == nums[i - k]: q.popleft()
)
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
from collections import deque
if not nums: return []
# 初始化单调队列,对任意 i > j,有 q[i] >= q[j]
q = deque()
for x in nums[:k]:
while q and q[-1] < x: # 注意这里是非严格单调的
q.pop()
q.append(x)
# print(q)
ret = [q[0]] #
for i in range(k, len(nums)):
if q[0] == nums[i - k]: # 因为是通过值判断,所以需要保留所有相同的最大值,所以队列是非严格单调的
q.popleft()
while q and q[-1] < nums[i]:
q.pop()
q.append(nums[i])
ret.append(q[0])
# print(q)
return ret