📅  最后修改于: 2023-12-03 14:54:56.422000             🧑  作者: Mango
队列是一种抽象数据类型,它实现了先进先出(FIFO)的数据结构,即在队列中添加一个元素时,它将被添加到队列的尾部,而在弹出元素时,它将从队列的头部被弹出。这种数据结构是非常常见的,例如在操作系统中就经常使用队列来管理进程的执行。问题 11 是一个关于队列的经典问题,也是一道面试题常见的问题。
问题 11 是这样的:有一个整数数组 nums 和一个大小为 k 的滑动窗口,请找出其中所有滑动窗口里的最大值。
例如,给定 nums = [1,3,-1,-3,5,3,6,7],以及 k = 3。
滑动窗口的位置 | 最大值 --- | --- [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
你需要按顺序返回滑动窗口中每个位置的最大值。
众所周知,队列在滑动窗口问题中是非常实用的,因为它能够在保持数据先进先出的同时,还能够维护一个单调递减的序列,非常适合找到窗口中的最大值。我们用双端队列来实现这个想法。
from collections import deque
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
if not nums:
return []
if k == 1:
return nums
dq = deque()
res = []
for i, num in enumerate(nums):
# 弹出队尾元素,保证队列中只有k个元素
while dq and nums[dq[-1]] < num:
dq.pop()
dq.append(i)
# 弹出队头元素,保证队列中只有k个元素
while dq and i - dq[0] >= k:
dq.popleft()
# 当i >= k - 1 时才开始添加元素进入res列表
if i >= k - 1:
res.append(nums[dq[0]])
return res
时间复杂度:O(N),其中 N 是数组 nums 的长度。每个元素都最多被插入和弹出队列一次。
空间复杂度:O(k),与队列的大小相关。
问题 11 是一个关于队列的经典问题,通过维护一个单调递减的队列,我们可以在 O(N) 的时间内解决这个问题。同时,这也是一个很好的面试题,既考察了对滑动窗口的理解,又考察了对队列的掌握程度。