Sliding Window Maximum,LeetCode,239

题目描述

给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

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

示例

输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3 输出: [3,3,5,5,6,7] 解释:

滑动窗口的位置 最大值


[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

解题思路

可以使用双端队列(deque)来解决这个问题。双端队列可以在两端进行插入和删除操作,非常适合维护一个滑动窗口内的最大值。

具体步骤

  1. 初始化一个双端队列和一个结果数组。
  2. 遍历数组 nums
    • 对于每个元素,从队列的尾部开始,移除所有小于当前元素的值,因为这些值不可能成为后续窗口的最大值。
    • 将当前元素的索引添加到队列的尾部。
    • 如果队列的头部元素(即最大值的索引)已经不在当前窗口内(即索引小于窗口的左边界),将其移除。
    • 当窗口形成后(即遍历的元素数大于等于 k),将队列头部的元素(即当前窗口的最大值)添加到结果数组中。
  3. 返回结果数组。

代码实现

from collections import deque

def maxSlidingWindow(nums, k): if not nums or k <= 0: return []

result = []
deque = deque()

for i in range(len(nums)):
    # 移除所有小于当前元素的值
    while deque and nums[deque[-1]] < nums[i]:
        deque.pop()

    # 添加当前元素的索引
    deque.append(i)

    # 移除不在窗口内的元素
    if deque[0] < i - k + 1:
        deque.popleft()

    # 窗口形成后,添加最大值到结果数组
    if i >= k - 1:
        result.append(nums[deque[0]])

return result

示例

nums = [1, 3, -1, -3, 5, 3, 6, 7] k = 3 print(maxSlidingWindow(nums, k)) # 输出: [3, 3, 5, 5, 6, 7]

复杂度分析

  • 时间复杂度:O(n),每个元素最多被添加和移除一次。
  • 空间复杂度:O(k),双端队列最多存储 k 个元素的索引。

这种方法利用了双端队列的特性,高效地解决了滑动窗口最大值的问题。希望这个解答对你有帮助!如果有更多问题,欢迎继续提问。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注