单调队列

单调队列分为单调递增队列和单调递减队列,由于二者差不多,这里只介绍下单调递减队列。


用途:

单调队列可以用来维护区间最值。

单调递减队列维护区间最大值,单调递增队列维护区间最大值。


实现:

现在我们用单调递减队列维护长度为L的区间的最大值。现将下标为x的元素a入队。用b表示队列尾元素。(这里可能描述的不是很清,因为这个结构的使用违背了队列的用法,可以看下面的例子)

1.b>a

b出队,直到队列为空,或b<a,则a入队。

2.假设队列首元素c下标为y

y < x-L+1,则c出队,直到y>=x-L+1。

3.此时队列首元素c是区间[x-L+1,x]的最大值。


例子:

给定数列:3 ,1 ,5 , 7 ,4 ,2 , 1。维护区间长度为3的最大值

1.3入队        3

2.1入队        3,1

3.3,1出队,5入队      5       区间[1,3]的最大值为5

4.5出队,7入队       7        区间[2,4]的最大值为7

5.4入队     7,4          区间[3,5]的最大值为7

6.2入队     7,4,2        区间[4,6]的最大值为7

7.1入队,7出队      4,2,1    区间[5,7]的最大值为4


性质:

1.队列里的元素是单调递减的。

2.假如维护区间长度为L的最大值,刚入队的元素下标为x,则队列首元素是区间[x-L+1,x]的最大值。

3.由于每个元素只会入队和出队各一次,所以复杂度为0(n)。


现在重点介绍下性质2,我们应该好好体会一下这种思想。

现在我们求出区间[x,y]的最大值a,此时我们要求[x+1,y+1]区间的最大值,假如下标为y+1的元素b > a,那么该区间的最大值肯定是b,但b < a呢?拿b和区间[x+1,y]的所有数比较一次?这样复杂度太高了。我们想一下我们在求[x,y]的最大值时,[x+1,y]的信息我们都是知道的。我们可以把这些值保存下来,但对于i < j && val[i] < val[j]的元素i我们是没有必要保存的,我们只要保存j就可以了(仔细体会下)。这时我们按照前面的方法维护单调队列。此时队首元素为v,下标为t(x+1 <= t <= y+1),为啥t就是区间[x+1,y+1]的最大值呢。因为这是递减队列,所以在区间[x+1,y+1]中v前面的元素必然小于v,不然会留在队列中,v后面的元素也必然小于v,不然v不会留在队列中,所以v是最大值。

猜你喜欢

转载自blog.csdn.net/jiangzhiyuan123/article/details/80042359