栈和队列 239. 滑动窗口最大值

239. 滑动窗口最大值

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

示例:

输入: nums = [1,3,-1,2,5,3,6,7], 和 k = 2
输出: [3, 3, 2, 5, 5, 6, 7]
解释: 
  滑动窗口的位置                最大值
---------------               -----
[1  3] -1  2  5  3  6  7       3
 1 [3  -1] 2  5  3  6  7       3
 1  3 [-1  2] 5  3  6  7       2
 1  3  -1 [2  5] 3  6  7       5
 1  3  -1  2 [5  3] 6  7       5
 1  3  -1  2  5 [3  6] 7       6
 1  3  -1  2  5  3 [6  7]      7

思路:双端队列

使用一个双端队列记录窗口滑动过程,注意:队列中放入的是索引
遍历nums:

  1. 将第一个元素放入队列
  2. 遍历之后的元素时,判断其与队列中前一个元素值的大小关系:
    若大于前一个元素,则将前一个元素弹出,并继续向前判断,最终将其添加到队列
    若小于前一个元素,则将其添加到队列中
    以上操作的目的是,将当前窗口的最大元素放在队列的首端
  3. 为了保证队列中元素都为当前窗口的元素,在每次添加元素索引之后,还需做一步判断:
    判断当前索引 - 队首索引 是否等于 窗口宽度k
    若相等,说明队首元素的索引已经超出当前窗口,将其弹出
  4. 将队首元素放入结果集
  5. 返回结果集中k-1之后的元素,因为k-1前不是有效的滑动窗口

代码实现:

class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        deque = []
        ret = []
        for i in range(len(nums)):
            while deque and nums[i] > nums[deque[-1]]:
                deque.pop()
            deque.append(i)
            if i - deque[0] == k:
                deque.pop(0)
            ret.append(nums[deque[0]])
        return ret[k-1:]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值