单调队列是指:队列中元素之间的关系具有单调性,而且,队首和队尾都可以进行出队操作,只有队尾可以进行入队操作。
顾名思义就是一个有规律的队列,这个队列的规律是:所有在队列里的数都必须按递增(或递减)的顺序列队,如果真有这么一个队列,那么队列的头是不是就是最小(或最大)的呢?
我们简单了解一些单调队列的思想,假如你在饭堂打饭时,有个人人高马大,急匆匆跑过来,看排了这么一长串队,心中急躁,从队列最后的一个人开始,看见好欺负的就赶走,自己站着,直到干不过的就停下,这样排在前面的认肯定是最高大威猛的。
这个队伍就可以认为是一个”单调队列“(单调递减队列),也就是允许两端弹出,只允许一端插入的队列(允许两端插入,只允许一端弹出的也属于双端队列)。
百度百科中单调队列的解释是
不断地向缓存数组里读入元素,也不时地去掉最老的元素,不定期的询问当前缓存数组里的最小的元素。
用单调队列来解决问题,一般都是需要得到当前的某个范围内的最小值或最大值。
举个例子:有 7 6 8 12 9 10 3 七个数字,现在让你找出范围( i-4,i )
的最小值。
那我们就可以这样模拟一遍。
先初始化{ 0 }
(表示i=0时的值),i从1开始
i=1 ->{ 0 }
(表示i=1时,在其范围内最小的值为0)-> 7进队{ 7 }
;
i=2->{ 7 }
(表示i=2时,在其范围内最小的值为7)-> 6比7小,7出,6进{ 6 }
;
i=3->{ 6 }
(表示i=3时,在其范围内最小的值为6)->8比6大,8进{ 6, 8}
;
i=4->{ 6, 8}
(表示i=4时,在其范围内最小的值为6)-> 12比8大,12进{6, 8 , 12}
;
i=5->{6, 8 , 12}
(表示i=4时,在其范围内最小的值为6)-> 9比12小,12out,9比8大,9进{6,8, 9}
;
i=6->{6,8, 9}
但是 单调队列中元素6的下标是2,不在(2, 6],中,故6 out,这就是单调队列的精髓了。
故单调队列为{ 8,9 }
(表示i=5,时,在其范围内最小的值为8)->10比9大,10进 最终 单调队列为{ 8,9, 10}
;
i=7->{ 8,9, 10}
(表示i=6,时,在其范围内最小的值为8)-> 3比单调队列为{ 8,9, 10}
的任意值都小,故全out,最终集合为{ 3 }
;
单调队列的核心是得到当前的某个范围内的最小值或最大值。