思路
一、 单调队列
单调队列:单调递减或单调递增的队列。单调队列不同场景不同写法,重点是保持递增或递减。
- 难点:如何求滑动窗口内的最大值?
答:队列放入滑动窗口里的数字,窗口移动,队列也一进一出,每次移动后,队列告知最大值;这个单调队列有pop()、push()、front()函数,front返回队列最大值。 - pop:若窗口移除的value等于单调队列的出口元素,队列弹出出口元素,否则,不操作。
- push:若push的value大于单调队列的入口元素,队列弹出入口元素,直到push的数字小于等于入口元素为止。
- front:返回最大值。
用deque,它的popleft()时间复杂度O(1)
注意:这里的pop和push仅适用于本题
from collections import deque
class MyQueue:
def __init__(self):
#用list实现单调队列
self.qu=deque()
def pop(self,value):
#每次弹出前,判断当前值与队列出口元素是否相等,相等则弹出;并且,队列不为空
if self.qu and self.qu[0]==value:
#移除下标0的元素
self.qu.popleft()
def push(self,value):
#若当前值大于队列入口元素,将队列后端元素弹出,直到push的value小于等于队列入口元素
#保证队列从大到小排序
while self.qu and value > self.qu[-1]:
self.qu.pop()
self.qu.append(value)
def front(self):
#获取当前队列最大值,直接返回队列前端数值,也是队列出口元素
return self.qu[0]
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
myque=MyQueue()
res=[]
#窗口
for i in range(k):
myque.push(nums[i])
#加入初始窗口的最大值
res.append(myque.front())
#窗口移动
for j in range(k,len(nums)):
#滑动窗口移除最前面元素
myque.pop(nums[j-k])
#滑动窗口加入新元素
myque.push(nums[j])
#加入当前窗口最大值
res.append(myque.front())
return res