模板:递增队列或是递减队列只需要修改删除队尾元素的判断条件即可。
原理 以递增队列举例:
以一个长度为k的移动窗口从k处开始移动,遍历数组中的每个元素,添加到队列末尾并且于前一个元素相比较,直到有一个元素大于当前元素,退出循环,将当前元素加入队列,并且将位置坐标另记入一个位置数组。寻找k长度窗口内的最大值则只需要在位置数组遍历,第一个大于等于i的就是所求的最大值。
···
include<iostream>
include<cstdio>
include<cstring>
include<string>
include<queue>
include<map>
include<vector>
include<algorithm>
include<stack>
include<set>
using namespace std;
typedef long long ll;
const int N=1000010;
const int inf=0x3f3f3f;
int n,k;
int q[N],mk[N],a[N];
void qmax()
{
int i,st=1,tt=1;
for(i=1;i<=n;i++)
{
while(tt<st&&q[st-1]<=a[i]) st--;
q[st]=a[i];mk[st]=i;st++;
if(i>=k)
{
while(tt<st&&mk[tt]<=i-k) tt++;
printf("%d ",q[tt]);
}
}
}
void qmin()
{
int i,st=1,tt=1;
for(i=1;i<=n;i++)
{
while(tt<st&&q[st-1]>=a[i]) st--;
q[st]=a[i];mk[st]=i;st++;
if(i>=k)
{
while(tt<st&&mk[tt]<=i-k) tt++;
printf("%d ",q[tt]);
}
}
}
int main() {
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
qmin();
printf("\n");
qmax();
printf("\n");
return 0;
}···