剑指 Offer 59 - I. 滑动窗口的最大值(困难)
给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。
剑指Offer 30. 包含 min 函数的栈 ,其使用 单调栈 实现了随意入栈、出栈情况下的 O(1) 时间获取 “栈内最小值” 。本题同理,不同点在于 “出栈操作” 删除的是 “列表尾部元素” ,而 “窗口滑动” 删除的是 “列表首部元素” 。


到这应该可以动手实现了。
只要加入的值比现有的都大,窗口往右移,该窗口的最大值就不受该值前面的元素影响,所以可以把前面的元素移除队列。
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
from collections import deque
if not nums or k==0: return []
i, j, end = 0, 0, len(nums)
top = deque()
res = []
while j<k: # 未形成窗口
while top and top[-1]<nums[j]:
top.pop()
top.append(nums[j])
j += 1
res.append(top[0])
while j<end: # 形成窗口后
left = nums[i]
if left == top[0]:
top.popleft()
i += 1
while top and top[-1]<nums[j]:
top.pop()
top.append(nums[j]) # 先加入新元素 再判断窗口最大值
res.append(top[0])
j += 1
return res
剑指 Offer 59 - II. 队列的最大值
请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。
若队列为空,pop_front 和 max_value 需要返回 -1
1队列+1双端队列
self.queue = queue.Queue()
self.deque = queue.deque()
两个类的区别,队列不能判断为not b,也不能下标索引

class MaxQueue:
from collections import deque
def __init__(self):
self.de = deque()
self.top = deque()
def max_value(self) -> int:
if not self.de: return -1
return self.top[0]
def push_back(self, value: int) -> None:
while self.top and self.top[-1] < value:
self.top.pop()
self.top.append(value)
self.de.append(value)
def pop_front(self) -> int:
if not self.de: return -1
out = self.de.popleft()
if self.top[0] == out:
self.top.popleft()
return out
# Your MaxQueue object will be instantiated and called as such:
# obj = MaxQueue()
# param_1 = obj.max_value()
# obj.push_back(value)
# param_3 = obj.pop_front()
官方题解,思想是一样的
import queue
class MaxQueue:
"""1队列+1双端队列"""
def __init__(self):
self.queue = queue.Queue()
self.deque = queue.deque()
def max_value(self) -> int:
if self.deque:
return self.deque[0]
else:
return -1
# return self.deque[0] if self.deque else -1 或者这样写
def push_back(self, value: int) -> None:
while self.deque and self.deque[-1] < value:
self.deque.pop()
self.deque.append(value)
self.queue.put(value)
def pop_front(self) -> int:
if not self.deque: return -1
ans = self.queue.get()
if ans == self.deque[0]:
self.deque.popleft()
return ans
作者:z1m
链接:https://leetcode-cn.com/problems/dui-lie-de-zui-da-zhi-lcof/solution/ru-he-jie-jue-o1-fu-za-du-de-api-she-ji-ti-by-z1m/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
本文介绍了如何利用双向队列和单调队列解决滑动窗口最大值及队列最大值问题。通过不断更新队列,保持队列头部始终为当前窗口或队列的最大值,从而在O(1)的时间复杂度内完成查询操作。具体实现包括在窗口滑动时删除队列首部元素,在队列末尾添加新元素并维护最大值。
255

被折叠的 条评论
为什么被折叠?



