暴力方法,遍历一遍的过程中每次从窗口中在找到最大的数值,是$O(n × k)$的算法会超时。
想通过优先级队列解决,但是大顶堆每次只能弹出最大值,此时不能保证大顶堆维护的都是滑动窗口里的数值。
此时就需要自定义一种队列,在滑动窗口移动的时候,既能移除元素,也能继续添加元素,并且还需保证,返回的队首元素是当前窗口的最大值。
队列不需要维护窗口里的所有元素,只需要维护有可能成为窗口里最大值的元素即可,同时保证队里的元素数值是由大到小的。所以需要一个单调队列。
设计单调队列的时候,pop,和push操作要保持如下规则:
1)pop(value):如果窗口移除的元素value等于单调队列的出口元素,那么队列弹出元素,否则不需要做任何操作;
2)push(value):如果push的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到push元素的数值小于等于队列入口元素的数值为止,也就是需要保证队列的单调递减。
保持如上规则,每次窗口移动的时候,只要调用que.front()就可以返回当前窗口的最大值。