单调队列:队列内的元素值是单调的,递增或者递减
可理解为:分成两个操作:
1.队头出队:当队头的元素从窗口滑出是,队头元素出队。(此时就是head++指向了下一个元素)
例如,队头的9要滑出窗口,那么就直接pass它
2.队尾入队:
当新的元素划入窗口时,把新元素从队尾插入,此时有两种情况:
(1):直接插入:新元素小于队尾元素时就直接从尾插入即可(这里用的是递减)(tail++);因为它有可能在前面的最大值出去之后成为新的最大值。
例如:插入4
(2)先删后插:当新元素大于尾结点时,那就直接删除队尾元素(因为它已经没可能成为最大值了),就直接tail--,从队尾出队。一直删除,直到对空或者遇到一个大于它的值,插入在他后面(++tail)
例:在6,4上插入9
这样处理之后每次都能从队头得到你想要的值。
注意:队列要存储窗口元素的下标值,以便于判断队头的一个出队。
以下是简单的c实现:
#include <stdio.h>
//这个是递增的队列
#define N 100
int a[N],q[N];
int main()
{
int n,k;
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",a+i);
scanf("%d",&k); //窗口的大小
int h=0,t=-1; //队头和队尾
for (int i=1;i<=n;i++)
{
//队头出队
if (h<=t&&i-k>q[h])
h++;
//先删后入
while (h<=t&&a[q[t]]>=a[i])
t--;
q[++t]=i;
//同时确保窗口大小是正确的
if (i>=k)
printf("%d ",a[q[h]]);
}
printf("\n");
return 0;
}