首页 > 其他 > 详细

单调队列

时间:2014-02-07 09:27:49      阅读:328      评论:0      收藏:0      [点我收藏+]

单调队列,顾名思义就是具有单调性的队列O(∩_∩)O~,一般的队列只能从队尾入队、队首出队;为了保持单调队列的单调性,单调队列除具有这两种性质外,还可以从队尾出队。
以单增的单调队列为例,当元素t要入队时,先要从队尾依次弹出所有>=t的元素,再将t加在队尾。
举个例子,如果序列:1 3 -1 -3 10要构成单调队列,
先将元素“1”放入队列中,以初始化队列,
接着元素“3”要入队,队尾元素“1”比“3”小,因此“3”可以直接入队,队列变为1 3,
接着“-1”要入队,从队尾依次弹出元素“3”“1”后将“-1”入队,队列变为-1,
同理“-3”入队后,队列变为-3,
“10”入队后,队列变为-3 10

单调队列有什么用呢?看一道例题:(poj2823)
给定含有n个元素的无序序列a[],和一个整数k,要求求出a[]中每连续k个元素组成的序列中的最小值(或最大值),这样的值可能有1个或n-k+1个。
比较简单的方式,是每次都将k个数的最值找出,具有O(K*n)的时间复杂度。但如果用单调队列的话,我们可以在O(n)的时间内求解,原因是每个元素最多入队一次、出队一次。
要解决该题,我们还要记录每个元素在原序列中的位置p,每次只需从队首开始找到跟当前元素a[i]距离不大于k的元素(即是i-p+1<=k)输出即可。

一、 什么是单调(双端)队列
单调队列,顾名思义,就是一个元素单调的队列,那么就能保证队首的元素是最小(最大)的,从而满足动态规划的最优性问题的需求。
单调队列,又名双端队列。双端队列,就是说它不同于一般的队列只能在队首删除、队尾插入,它能够在队首、队尾同时进行删除。
【单调队列的性质】
一般,在动态规划的过程中,单调队列中每个元素一般存储的是两个值:
1、在原数列中的位置(下标)
2、 他在动态规划中的状态值
而单调队列则保证这两个值同时单调。
从以上看,单调队列的元素最好用一个类来放,不这样的话,就要开两个数组。。。

单调队列:单调队列 即保持队列中的元素单调递增(或递减)的这样一个队列,可以从两头删除,只能从队尾插入。单调队列的具体作用在于,由于保持队列中的元素满足单调性,对手元素便是极小值(极大值)了。

 

单调队列的舞台

 

由于单调队列的队头每次一定最小值,故查询为O(1)。

 

进队出队稍微复杂点:

 

进队时,将进队的元素为e,从队尾往前扫描,直到找到一个不大于e的元素d,将e放在d之后,舍弃e之后的所有元素;如果没有找到这样一个d,则将e放在队头(此时队列里只有这一个元素)。

 

出队时,将出队的元素为e,从队头向后扫描,直到找到一个元素f比e后进队,舍弃f之前所有的。(实际操作中,由于是按序逐个出队,所以每次只需要出队只需要比较队头)。

 

每个元素最多进队一次,出队一次,摊排分析下来仍然是 O(1)。

 

上面的话可能还是没能讲出单调队列的核心:队列并不实际存在的,实际存在的是具有单调性的子序列。对这个子序列按心中的队列进行操作,譬如在进队时丢弃的元素,虽然它不存在于这个子序列里,但是还是认为他存在于队列里。

 

另外,进队的顺序和出队的顺序并不一定相同,因为这个队列本身是隐含存在的,可以在进队时看成一个队列,出队时看成另一个队列,只要出队的元素在队列中就行。可以想象成一个队列只有头和身,另一个队列只有身和尾,而这身是共用的。

单调队列

原文:http://www.cnblogs.com/zhaoxinshanwei/p/3539029.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!