是队列的一种应用优化形式。
使用场景: 求一段区间长度的最大最小值 原理:
对于一个序列:1 3 -1 -3 5 3 6 7, 求其长度为3的连续区间中最大值并输出。
通常做法是 , 建一个长度为3的队列, 尾入队时头出队, 然后遍历队列求极值。
存在一个优化点, 对于 1 3 -1, 若求的是最小值, 那么显然往后滑动时不会选到 1 3, 因为 -1 始终在, 故可以直接踢去 1 和 3, 这样只留下当前的最小值。
此时队列中元素只有 -1 接下来滑动一位, 对于 -3 比 -1 小, 按刚才的思路, -1会被踢出, -3此时成为队列中唯一的元素, 也就说此时的区间最小值为-3。
继续滑动, 新元素为 5 > -3 故可以直接入到队尾不做处理。
继续滑动, 新元素为 3 > 队尾的5, 根据之前的思路可以直接踢去5, 入队3。
继续滑动, 新元素为 6 < 3, 故不变化, 但此时区间应为[5 3 6]
, -3已经滑出去, 不能作为区间极值, 故把队头出队, 此时3就是队头。
代码:
for(int i = 1; i <= n; i++)
{
while(hh <= tt && i - m > q[hh]) hh++;
while(hh <= tt && a[q[tt]] >= a[i]) tt--;
q[++tt] = a[i];
if(i >= m) cout << a[q[hh]] << endl;
}