给你一个整数数组 nums
,有一个大小为 k
的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k
个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
# deque 是Python标准库 collections 中的一个类,实现了两端都可以操作的队列,相当于双端队列
# append(item),添加一个数据到队列的尾部。与列表的append()方法功能相似。
# appendleft(item),添加一个数据到队列的头部。与append()的添加方向相反。
# pop(),将队列尾部的数据弹出,并作为返回值。
# popleft(),将队列头部的数据弹出,并作为返回值。
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
# 视频里讲的是左边pop出,右边push进(但push进的时候涉及右边出和进 视频里用push_back和pop_back),左边大右边小
# 这里尝试右边pop出,左边push进(但涉及appendleft和popleft),左边小右边大
def pop(que, val): #(右出)
# 如果没有这个if条件会怎样。因为但凡是需要pop的好像都是pop最大值
# 回答:必须要有if。否则,比如-1 3 1 -3,滑动到3 1 -3的时候要pop出-1,但此时-1已经被3卷走了,所以滑动窗口里本来也没-1,因此不需要进行pop操作。
# if not que and que[-1] == val: 判断条件不是not que而是que,表示que不是空而是有值的时候
if que and que[-1] == val: # 此时pop的就是当前窗口最大值
que.pop()
return que
def push(que, val): # (左出左进)
while que and que[0] < val:
que.popleft()
que.appendleft(val)
return que
que = deque()
res = []
for i in range(len(nums)):
if i < k:
que = push(que, nums[i])
else:
res.append(que[-1])
# 注意append是用小括号()而不是中括号[]
que = push(que, nums[i])
que = pop(que, nums[i - k])
# 上两行交换会否有影响?
res.append(que[-1])
return res
# 下面是卡哥的
# from collections import deque
# class MyQueue: #单调队列(从大到小
# def __init__(self):
# self.queue = deque() #这里需要使用deque实现单调队列,直接使用list会超时
# #每次弹出的时候,比较当前要弹出的数值是否等于队列出口元素的数值,如果相等则弹出。
# #同时pop之前判断队列当前是否为空。
# def pop(self, value):
# if self.queue and value == self.queue[0]:
# self.queue.popleft()#list.pop()时间复杂度为O(n),这里需要使用collections.deque()
# #如果push的数值大于入口元素的数值,那么就将队列后端的数值弹出,直到push的数值小于等于队列入口元素的数值为止。
# #这样就保持了队列里的数值是单调从大到小的了。
# def push(self, value):
# while self.queue and value > self.queue[-1]:
# self.queue.pop()
# self.queue.append(value)
# #查询当前队列里的最大值 直接返回队列前端也就是front就可以了。
# def front(self):
# return self.queue[0]
# class Solution:
# def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
# que = MyQueue()
# result = []
# for i in range(k): #先将前k的元素放进队列
# que.push(nums[i])
# result.append(que.front()) #result 记录前k的元素的最大值
# for i in range(k, len(nums)):
# que.pop(nums[i - k]) #滑动窗口移除最前面元素
# que.push(nums[i]) #滑动窗口前加入最后面的元素
# result.append(que.front()) #记录对应的最大值
# return result