思路:
最小值和最大值分开来做,两个for循环是类似的,都做以下四步:
1.解决队首已经出窗口的问题;
2.解决队尾与当前元素a[i]不满足单调性的问题;
3.将当前元素下标加入队尾;
4.如果满足条件则输出结果;
需要注意的细节:
1.上面四个步骤中一定要先3后4,因为有可能我们需要输出的正是新加入的那个元素;
2.队列中存的是原数组的下标,取值时要再套一层,a[q[]];
3.算最大值前注意将hh和tt重置;
4.hh从0开始,数组下标也要从0开始。
#include<iostream>
using namespace std;
const int N=1000010;
int q[N],a[N],hh,tt=-1;
int main(){
int n,k;
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
for(int i=0;i<n;i++){
if(i-k+1>q[hh]) hh++;//若队头超出窗口,队头出队
while(hh<=tt&&a[q[tt]]>=a[i]) tt--;//若队尾元素大于等于待入队的元素(不单调),队尾出队
q[++tt]=i;//新下标加到队尾
if(i-k+1>=0) printf("%d ",a[q[hh]]);//此时队头就是最小值
}
printf("\n");
//最大值同理
hh=0;tt=-1;//重置两个指针
for(int i=0;i<n;i++){
if(i-k+1>q[hh]) hh++;
while(hh<=tt&&a[q[tt]]<=a[i]) tt--;
q[++tt]=i;
if(i-k+1>=0) printf("%d ",a[q[hh]]);
}
}