单调队列解决滑动窗口最大值问题

本文介绍了如何使用单调队列解决滑动窗口最大值的问题,避免了在删除最大值时重新遍历窗口的低效操作。通过删除无效数据并保持队列单调性,可以高效地更新窗口的最大值。示例代码展示了如何实现这个方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天遇到一道滑动窗口最大值问题239滑动窗口最大值,发现单调队列是解决这类问题的高效方法,遂加以记录。

单调队列:即保持单调有序的队列。底层数据结构使用双端队列比较好,C++需要添加<deque>头文件。

滑动窗口最大值问题中,我们关心的是滑动窗口内的最大值,当滑动窗口向右移动一位时,需要删除一个元素和添加一个元素。对于添加元素来说比较好办,如果添加的元素大于当前最大值则替换其为最大值。而删除元素,如果删除的是最大值,则需要重新遍历滑动窗口内容,造成效率的低下。

研究此问题发现,如下图,当添加的元素是4,时,前面的所有小于4的元素均变成无效数据(如果删除5,则4是最大值,轮不到123当最大值;如果删除了5又删除了4,因为123在4之前进入滑动窗口,所以删除4之前123已经被删除,所以也轮不到123当最大值)。

因此滑动窗口右移,一:删除窗口左端元素,如果和队首元素相同,则队首元素出队,否则什么也不做;二:添加窗口右边元素,新元素入队时,都将前面所有比自己小的元素删除再入队
在这里插入图片描述

//单调队列
struct MonotonicQue{
    deque<int>que;
    void push(int n){
        while(!que.empty() && que.back()<n){
            que.pop_back();
        }
        que.push_back(n);
    }
    void pop(int n){
        if(n==que.front())
            que.pop_front();
    }
    int top(){
        return que.front();
    }
};

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        MonotonicQue monQue;
        //添加前k个元素到单调队列
        for(int i=0;i<k;i++)
            monQue.push(nums[i]);
        vector<int>ans;
        ans.push_back(monQue.top());
        for(int i=k;i<nums.size();i++){
            monQue.pop(nums[i-k]);
            monQue.push(nums[i]);
            ans.push_back(monQue.top());
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值