python实现leetcode239题:滑动窗口最大值 基于单调队列实现线性时间,代码更新到几行,注释清晰

题目描述

给定一个数组 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

提示:

你可以假设 k 总是有效的,在输入数组不为空的情况下,1 ≤ k ≤ 输入数组的大小。

进阶:

你能在线性时间复杂度内解决此题吗?

思路:

用python自带的list实现双端队列,利用双端队列实现单调队列
用双端队列来实现单调队列(严格单调) 普通队列不能从尾部弹出元素,双端可以
单调栈和单调队列可以参考 https://endlesslethe.com/monotone-queue-and-stack-tutorial.html
此题不用单调栈的原因是不能从头部(栈底)弹出元素

新的代码,更简洁,更快了

思路:

维持队列单调性的时候,用while替换for循环

# 用双端队列来实现单调队列(严格单调) 普通队列不能从尾部弹出元素,双端可以
# 单调栈和单调队列可以参考 https://endlesslethe.com/monotone-queue-and-stack-tutorial.html
# 此题不用单调栈的原因是不能从头部(栈底)弹出元素
# from collections import deque


class Solution(object):
    def maxSlidingWindow(self, nums, k):
        #单调队列中放的是索引,注意比较的时候是比较对应值,不要粗心做错了
        monotonicQueue = []
        res = []
        for i in range(len(nums)):
            # 删除单调队列中比新进元素不大于的元素
            # 注意是值与值比较,不要粗心搞成索引与值比较
            while monotonicQueue and nums[monotonicQueue[-1]] <= nums[i]:
                monotonicQueue.pop()
            # 添加新元素到队尾
            monotonicQueue.append(i)
            # 删除窗口内过期的元素,为什么不写在for循环第一步是因为如果队列中没有元素的话就会报错了
            if monotonicQueue[0] == i - k:
                monotonicQueue.pop(0)
            # 为了初始化时候还未到k个的时候,重复输出, 以及nums为1,2 不为k的时候也能输出数
            if i >= k - 1 or i + 1 >= len(nums):
                # 注意要把数值放到res里面,不是索引
                res.append(nums[monotonicQueue[0]])
        return res





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值