基础算法学习--单调队列

单调队列模板

  • 对于在队列的数来说他们都是单调的,该模板队头为队列最小值下标,队尾为队列最大值下标。
//共n个数据,k为维护的区间的长度
//遍历要处理的数据
for(int i = 0;i < n;i ++){
    //队头滑出区间
    while(hh <= tt && q[hh] <i - k + 1) hh ++;
    //保证入队的成为当前队列的最大值
    while(hh <= tt && a[q[tt]] >= a[i]) tt--;
    
    q[++ tt] = i;
}

例题--滑动区间

题目

求区间中的最大和最小值,分两行输出

🐴

#include<iostream>

using namespace std;

const int N = 1000010;

int a[N],q[N];
int n,k;
int hh = 0,tt = -1;

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 && q[hh] <i - k + 1) hh ++;     //该题保证一次一个滑出,所以可以用if
    //保证入队的成为当前队列的最大值
    while(hh <= tt && a[q[tt]] >= a[i]) tt--;
    
    q[++ tt] = i;
    
    if(i >= k - 1) printf("%d ",a[q[hh]]);
}
    cout << endl;
    
    hh = 0,tt = -1;
    for(int i = 0;i < n;i ++){
        if(hh <= tt && q[hh] < i - k + 1) hh ++;
        
        while(hh <= tt && a[q[tt]] <= a[i]) tt --;
        
        q[++ tt] = i;
        
        if(i >= k - 1) printf("%d ",a[q[hh]]);
    }
    
    return 0;
}
posted @ 2021-04-17 10:20  Xuuxxi  阅读(57)  评论(0)    收藏  举报