算法 -单调队列

单调队列

LeetCode 239. 滑动窗口的最大值


  • 队列中位于队首的元素是当前队列中的最大值
  • 每一次滑动窗口的时候不断更新当前队列中的队首元素

思路:

  1. 初始化一个队列,大小为k,队列头部始终存放当前窗口中的最大元素
  2. 当入队列的元素值大于队列中的元素,就从队尾开始pop元素,保证队列元素为单调排列
  3. 当入队列的元素值小于等于队首的元素,则直接入队列
  4. 返回当前队列的队首元素
  • 题目描述

给定一个数组 nums 和滑动窗口的大小 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 ≤ nums.length。

# 单调队列
# 1. 初始化一个队列,大小为k,队列头部始终存放当前窗口中的最大元素
# 2. 当入队列的元素值大于队列中的元素,就将队列的元素全部pop
# 3. 当入队列的元素值小于等于队首的元素,则直接入队列
# 4. 返回当前队列的队首元素
from collections import deque
class Solution:
    def maxSlidingWindow(self, nums, k):
        # 初始化一个队列,大小为窗口大小
        self.Monotone_que = deque() # 此处用列表容易出现超时
        # 初始化滑动窗口
        for i in range(k):
            self.push_element(self.Monotone_que,nums[i])
        res = []
        res.append(self.Monotone_que[0])
        # 遍历剩余元素
        for j in range(k,len(nums)):
            self.pop_element(self.Monotone_que,nums[j-k])
            self.push_element(self.Monotone_que,nums[j])
            res.append(self.Monotone_que[0])
        return res

    def pop_element(self,que,value):
        # 当要删除的值等于队首元素时,才进行弹出操作 // 由于此时是单调队列,队列中的元素呈递减排列
        # 如果弹出的元素值小于队首元素时,在push的时候就已经弹出,此时不用做处理
        if que and value == que[0]:
            que.popleft()

    def push_element(self,que,value):
        # 当队列不为空,切队列末尾的元素小于需要插入的元素时,就将队列末尾的元素弹出,保证队列始终呈单调递减排列
        # 切队首元素为队列中的最大值
        while que and que[-1] < value:
            que.pop()
        que.append(value)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值