AcWing-滑动窗口

文章讲述了如何使用C++中的双端队列(deque)来构建和维护单调队列,处理区间内的最大值和最小值查询问题。代码展示了如何在输入数组a中,根据给定的区间长度k,动态地找到每个区间内的最小值。
摘要由CSDN通过智能技术生成

单调队列模板题:

所需知识:单调队列

利用双端队列来实现单调队列;

双端队列与普通队列的不同处:双端队列删除元素时既可以删除队头又可以删掉队尾,其可以较好的维护单调队列的单调性;

双端队列的定义及主要函数:

deque<int>q;

q.push_front();//队头插入一个元素

q.push_back();//队尾插入一个元素

q.pop_front();//删除队头元素

q.pop_back();//删除队尾元素

q.front();//返回队头元素

q.back();//返回队尾元素

q.size();//返回队列大小

q.empty();//判断队列是否为空,若为空则返回true,反之,返回false

q.clear();//清空队列

q[i];//返回下标为i的元素

思路:构建一个单调队列,并维护其单调性,即使队列里面的元素严格单调,(若为单调递增,且a[i]<=a[q.back()],则将队尾元素删除,反之若为单调递减,则当a[i]>=a[q.back()]时删除),依次将每个元素下标入队;当队首元素已离开区间时,删除队头,最后在区间长度达到k之后输出每个区间对应的最小值与最大值。

#include <iostream>
#include <cstring>
#include <algorithm>
#include<queue>
const int N=1e6+10;
typedef long long ll;
using namespace std;

int n,k;
int a[N];
deque<int>q;
int main()
{
    cin>>n>>k;
    for(int i=1;i<=n;i++)
    cin>>a[i];
    for(int i=1;i<=n;i++){//i为区间尾的下标
        //维护队列单调性
        while(!q.empty()&&a[q.back()]>=a[i]) q.pop_back();
        //若队头不在区间内则删除
        if(!q.empty()&&q.front()+k<=i) q.pop_front();
        q.push_back(i);
        //当区间长度大于k时才输出
        if(i>=k) cout<<a[q.front()]<<' ';
    }    
    cout<<endl;
    //清空队列
    q.clear();
    for(int i=1;i<=n;i++){
        //维护队列单调性
        while(!q.empty()&&a[q.back()]<=a[i]) q.pop_back();
        //若队头不在区间内则删除
        if(!q.empty()&&q.front()+k<=i) q.pop_front();
        q.push_back(i);
        //当区间长度大于k时才输出
        if(i>=k) cout<<a[q.front()]<<' ';
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值