返回

滑窗里的Maximum 与LeetCode携手掌握滑动窗口算法

前端

LeetCode 239 滑动窗口最大值

LeetCode 239. 滑动窗口最大值是一个经典的算法题目,也是面试中的高频题。题目如下:

给定一个整数数组 nums 和一个整数 k,请找到一个大小为 k 的滑动窗口,使得窗口中的最大值最大。滑动窗口每次只能向右移动一位。

例如,对于数组 nums = [1, 3, -1, -3, 5, 3, 6, 7] 和 k = 3,滑动窗口的最大值分别是 [3, 3, 5, 5, 6, 7]。

滑动窗口算法

滑动窗口算法是一种解决连续子数组问题的一种有效方法。它的基本思想是:使用一个窗口在数组中滑动,每次滑动一步,并计算窗口中的最大值。当窗口滑到数组的末尾时,算法就结束了。

在 LeetCode 239. 滑动窗口最大值 这道题中,我们可以使用队列来实现滑动窗口。队列是一种先进先出(FIFO)的数据结构,它允许我们在窗口中快速地添加和删除元素。

具体来说,我们可以使用一个双端队列(Deque)来实现滑动窗口。双端队列是一种特殊的队列,它允许我们在队列的头部和尾部添加和删除元素。这样,当窗口滑到数组的末尾时,我们可以快速地删除队列中的第一个元素,并添加新的元素到队列的末尾。

代码实现

from collections import deque

def max_sliding_window(nums, k):
  """
  计算数组 nums 中大小为 k 的滑动窗口的最大值。

  参数:
    nums: 一个整数数组。
    k: 滑动窗口的大小。

  返回:
    一个列表,其中包含滑动窗口中的最大值。
  """

  # 检查输入是否合法。
  if k <= 0 or k > len(nums):
    raise ValueError("Invalid value of k.")

  # 创建一个双端队列来存储窗口中的元素。
  window = deque()

  # 在窗口中添加前 k 个元素。
  for i in range(k):
    while window and nums[i] > window[-1]:
      window.pop()
    window.append(nums[i])

  # 计算滑动窗口中的最大值。
  max_values = [window[0]]

  # 遍历数组中的剩余元素。
  for i in range(k, len(nums)):
    # 从窗口中删除第一个元素。
    if window[0] == nums[i - k]:
      window.popleft()

    # 在窗口中添加新的元素。
    while window and nums[i] > window[-1]:
      window.pop()
    window.append(nums[i])

    # 计算滑动窗口中的最大值。
    max_values.append(window[0])

  # 返回滑动窗口中的最大值。
  return max_values

时间复杂度和空间复杂度

滑动窗口算法的时间复杂度是 O(n),其中 n 是数组 nums 的长度。这是因为算法需要遍历数组中的每个元素,并在每次遍历时对窗口进行更新。

滑动窗口算法的空间复杂度是 O(k),其中 k 是滑动窗口的大小。这是因为算法需要使用一个队列来存储窗口中的元素,而队列的大小最多为 k。

总结

滑动窗口算法是一种解决连续子数组问题的一种有效方法。它可以用于解决各种各样的问题,例如 LeetCode 239. 滑动窗口最大值。滑动窗口算法的时间复杂度是 O(n),空间复杂度是 O(k)。