单调队列笔记

242 阅读1分钟

单调队列

这道题目,我们就维护两个队列,一个是最小值,一个是最大值.这里唯一的重点就是,每一次入队的时候,不需要管是不是比队头小,因为也许他现在小,但是在队头出队列后,他还在,而且是最小的值.

这道题目的时间限制卡得比较紧,需要用 O(n)O(n) 时间复杂度的算法来做。

这是一道单调队列的模板题,以求最小值为例:

我们从左到右扫描整个序列,用一个队列来维护最近 kk 个元素;
如果用暴力来做,就是每次都遍历一遍队列中的所有元素,找出最小值即可,但这样时间复杂度就变成 O(nk)O(nk) 了;
然后我们可以发现一个性质
如果队列中存在两个元素,满足 a[i] >= a[j] 且 i < j,那么无论在什么时候我们都不会取** a[i] **作为最小值了,所以可以直接将 a[i] 删掉;
此时队列中剩下的元素严格单调递增,所以队头就是整个队列中的最小值,可以用 O(1)O(1) 的时间找到;
为了维护队列的这个性质,我们在往队尾插入元素之前,先将队尾大于等于当前数的元素全部弹出即可;
这样所有数均只进队一次,出队一次,所以时间复杂度是 O(n)O(n) 的。