单调队列模板(滑动窗口的最大值)

有一个数组为1 3 -1 -3 5 3 6 7],有一个大小为k的滑动窗口,它从数组的最左边移动到最右边。

窗口中一次性只能存在k个数字

每次滑动窗口向右移动一个位置,现在要求输出每次窗口中的最小值

例如第一次: 1 3 -1 窗口中的最小值为-1

第二次:3 -1 -3 窗口中的最小值为-3

第三次:-1 -3 5 窗口中的最小值为-3

第四次 -3 5 3 窗口中的最小值为-3 依次类推

我们的做法是维护一个单调队列,并保持队列的单调递增性,这样每次队头元素就是这个窗口中的最小值

第一次,1进队,最小元素为1

第二次,3进队,没有破坏队列的单调性,队列为[1,3],最小元素1

第三次,-1进队,1比-1大,-1出队,3比-1大,3出队 此时最小元素为-1

第四次,-3进队,-1比-3大,-1出队,此时最小元素为-3

第五次,5进队,队列为[-3,5] 维持了单调性,最小元素为-3

第六次,3进队,5比3大,不满足单调性,5出队,[-3,3]保持了单调性,

第七次,-3被滑出窗口,6进队,[3,6]保持了单调性

第八次,7入队,[3,6,7]保持了单调性

算法结束

#include <iostream>
using namespace std;
const int N = 1000010;
int q[N],a[N],hh = 0,tt = -1;
int n,k;

int main(){
    cin >> n >> k;
    for(int i = 0;i < n;++i) scanf("%d",&a[i]);
    
    for(int i = 0;i < n;++i){
        if(hh <= tt && i - k + 1 > q[hh]) hh++; //窗口滑动
        while(hh <= tt && a[q[tt]] >= a[i]) tt--; //保持单调性
        q[++tt] = i;  //入队
        if(i >= k - 1) printf("%d ",a[q[hh]]); //队列中满足k个元素时才输出
        
    }

    return 0;
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值