154. 滑动窗口
题目链接https://www.acwing.com/problem/content/description/156/
题目:
思路:用队列来存储窗口里的最小\大值。如果要找窗口最小值,那么我们的队列里的数就应该是单调递增的,相反,找最大值,那么队列就是递减的。按找最小值来举例,当a[i]<a[i-1],那么a[i]存在就永无a[i-1]出头之日,就可以去掉a[i-1]。而当a[i]>a[i-1],那么a[i]在后面的数当中可能是最小的。这就是为什么求最小值,队列要单调递增的原因。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e6+10;
int a[N],b[N];
int main(){
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int f=0,r=-1;
for(int i=1;i<=n;i++){
if(f<=r&&i>b[f]+k-1) f++;//将超出窗口范围的数去掉
while(f<=r&&a[b[r]]>=a[i])r--;
b[++r]=i;
if(i>=k) printf("%d ",a[b[f]]);
}
cout<<endl;
f=0,r=-1;
for(int i=1;i<=n;i++){
if(f<=r&&i>b[f]+k-1) f++;
while(f<=r&&a[b[r]]<=a[i]) r--;
b[++r]=i;
if(i>=k) printf("%d ",a[b[f]]);
}
cout<<endl;
return 0;
}