重点:将队列中没有用的元素删除。
如果在窗口中存在i<j,ai>aj,那么在窗口向右移动的过程中,只要aj存在,那么ai就永远不可能成为最小值。应该被移除。
因此,当窗口移动到aj的那一刻,ai以及窗口中一切大于或者等于aj的元素都应该被移出队列。形成一个单调递增的队列,找队首就是最小值。找最大值的话反过来就行。
#include<iostream>
#include<queue>
using namespace std;
const int N=1e6+10;
int hh,tt=-1;//队列要定义队头和队尾
int n,k;
int a[N];
int q[N];//队列
int main(){
cin>>n>>k;
for(int i=0;i<n;i++){
cin>>a[i];
}
//最小值
for(int i=0;i<n;i++){
if(hh<=tt && q[hh]<i-k+1) hh++;//队头超出窗口,出队列
while(hh<=tt && a[q[hh]]>=a[i]) tt--;//如果窗口中的值大于即将进队列的元素,则删去。直到删到窗口中的值小于即将进队列的那个元素为止,形成一个单调递增的队列。
q[++tt]=i;//即将进队列的那个值进队列
if(i>=k-1) cout<<a[q[hh]]<<' ';//保证窗口中有k的数字时,开始输出队头(是最小值)。(i-1>=k)
puts("");//空格
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[hh]]>=a[i]) tt--;
q[++tt]=i;
if(i>=k-1) cout<<a[q[hh]]<<' ';
}
return 0;
}
标签:队尾,窗口,队列,tt,int,hh,单调 From: https://www.cnblogs.com/chenxinyue/p/17205665.html