返回

LeetCode 239 滑动窗口最大值:简洁优雅的双端队列应用

闲谈

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 的滑动窗口,并快速地更新窗口中的最大值。

双端队列的实现方式有很多种,但最常见的一种是使用数组。我们可以使用两个指针来表示双端队列的头部和尾部,并通过移动指针来添加或删除元素。

滑动窗口最大值算法

使用双端队列解决滑动窗口最大值问题的主要思想是,我们将滑动窗口中的元素存储在双端队列中,并维护一个最大值变量来记录滑动窗口中的最大值。当我们移动滑动窗口时,我们会将新元素添加到双端队列的尾部,并将旧元素从双端队列的头部删除。如果新元素大于最大值变量,我们将更新最大值变量。

以下是滑动窗口最大值算法的详细步骤:

  1. 初始化一个双端队列和一个最大值变量。
  2. 将滑动窗口中的元素添加到双端队列的尾部。
  3. 更新最大值变量,使其等于双端队列中最大的元素。
  4. 移动滑动窗口,将新元素添加到双端队列的尾部,并将旧元素从双端队列的头部删除。
  5. 重复步骤 3 和 4,直到遍历完整个数组。
  6. 返回最大值变量。

算法分析

滑动窗口最大值算法的时间复杂度是 O(n),其中 n 是数组的长度。这是因为算法只需要遍历数组一次,并且每次操作只需要常数时间。

滑动窗口最大值算法的空间复杂度是 O(k),其中 k 是滑动窗口的大小。这是因为算法只需要存储滑动窗口中的元素,而滑动窗口的大小是固定的。

总结

滑动窗口最大值算法是一种优雅而高效的算法,它可以解决各种滑动窗口问题。双端队列的使用使得算法的实现非常简单,并且可以轻松地扩展到其他滑动窗口问题。