AcWing 154. 滑动窗口
原题链接
简单
作者:
不会算法的小菜鸡
,
2021-07-16 12:18:38
,
所有人可见
,
阅读 275
C++ 代码
#include<iostream>
#include<cstdio>
using namespace std;
const int N=1e6+10;
int a[N],q[N],tt=-1,hh; //q里面存取的数组下标,如果用来存取数组值的话,那么无法保证队列里有三个数
int n,k;
int main()
{
scanf("%d %d",&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++;//滑出队头,应该滑动窗口里只有k个。只要队列达到了k个,每插入一个就要把队头滑出;并且i-k+1>q[hh]不能改为>0,因为队列里的数可能会小于三个,例如,当插入的前三个数大于当前插入的数,则q[0]=3,且队列里只有1个数
while(hh<=tt&&a[q[tt]]>=a[i]) tt--;//如果队列末尾的最后一个数比要插入的数大,就把这个数弹出,因为我们要求的是最小值,前面比插入数大的值没有任何用,所以直接弹出;
q[++tt]=i;//将i插入
if(i>=k-1) printf("%d ",a[q[hh]]);//i>=k-1表示i要大于窗口值才输出,如果i<k-1 就说明这个滑动窗口还没有达到k;
}
puts("");
hh=0,tt=-1;//要先初始化队列
for(int i=0;i<n;i++)
{
if(hh<=tt&&i-k+1>q[hh]) hh++;//滑出队头,应该滑动窗口里只有k个。只要队列里达到了k个,每插入一个就要把队头滑出;
while(hh<=tt&&a[q[tt]]<=a[i]) tt--;//如果队列末尾的最后一个数比要插入的数小,就把这个数弹出,因为我们要求的是最大值,前面比插入数大的值没有任何用,所以直接弹出;
q[++tt]=i;//将i插入
if(i>=k-1) printf("%d ",a[q[hh]]);//i>=k-1表示i要大于窗口值才输出,如果i<k-1 就说明这个滑动窗口还没有达到k;
}
return 0;
}