返回
LeetCode 239 滑动窗口最大值:简洁优雅的双端队列应用
闲谈
2023-11-15 12:57:39
def maxSlidingWindow(nums, k):
"""
Given an array of integers nums, a window of size k and an integer m,
return the maximum integer of all subarrays of size k.
Args:
nums (list[int]): List of integers
k (int): Size of the window
m (int): Maximum integer of all subarrays of size k
Returns:
list[int]: List of maximum integers of all subarrays of size k
"""
# Initialize the deque
deq = collections.deque()
# Initialize the result array
result = []
# Iterate over the nums array
for i in range(len(nums)):
# Remove the elements that are out of the window
while deq and deq[0] <= i - k:
deq.popleft()
# Remove the elements that are smaller than the current element
while deq and nums[deq[-1]] < nums[i]:
deq.pop()
# Append the current element to the deque
deq.append(i)
# Append the maximum element of the current window to the result array
if i >= k - 1:
result.append(nums[deq[0]])
return result
双端队列概述
双端队列是一种特殊的队列,它允许我们在两端添加或删除元素。这使得它非常适合用于解决滑动窗口问题,因为我们可以很容易地维护一个大小为 k 的滑动窗口,并快速地更新窗口中的最大值。
双端队列的实现方式有很多种,但最常见的一种是使用数组。我们可以使用两个指针来表示双端队列的头部和尾部,并通过移动指针来添加或删除元素。
滑动窗口最大值算法
使用双端队列解决滑动窗口最大值问题的主要思想是,我们将滑动窗口中的元素存储在双端队列中,并维护一个最大值变量来记录滑动窗口中的最大值。当我们移动滑动窗口时,我们会将新元素添加到双端队列的尾部,并将旧元素从双端队列的头部删除。如果新元素大于最大值变量,我们将更新最大值变量。
以下是滑动窗口最大值算法的详细步骤:
- 初始化一个双端队列和一个最大值变量。
- 将滑动窗口中的元素添加到双端队列的尾部。
- 更新最大值变量,使其等于双端队列中最大的元素。
- 移动滑动窗口,将新元素添加到双端队列的尾部,并将旧元素从双端队列的头部删除。
- 重复步骤 3 和 4,直到遍历完整个数组。
- 返回最大值变量。
算法分析
滑动窗口最大值算法的时间复杂度是 O(n),其中 n 是数组的长度。这是因为算法只需要遍历数组一次,并且每次操作只需要常数时间。
滑动窗口最大值算法的空间复杂度是 O(k),其中 k 是滑动窗口的大小。这是因为算法只需要存储滑动窗口中的元素,而滑动窗口的大小是固定的。
总结
滑动窗口最大值算法是一种优雅而高效的算法,它可以解决各种滑动窗口问题。双端队列的使用使得算法的实现非常简单,并且可以轻松地扩展到其他滑动窗口问题。