滑动窗口最大值–双端队列(详细解读)
利用一个双端队列来保存当前窗口中最大那个数在数组里的下标,双端队列新的头就是当前窗口中最大的那个数。通过该下标,可以很快地知道新的窗口是否仍包含原来那个最大的数。如果不再包含,我们就把旧的数从双端队列的头删除。
因为双端队列能让上面的这两种操作都能在 O(1) 的时间里完成,所以整个算法的复杂度能控制在 O(n)。
1、初始化窗口 k=3,包含 1,3,-1,把 1 的下标压入双端队列的尾部;
2、把 3 和双端队列的队尾的数据逐个比较,3 >1,把 1 的下标弹出,把 3 的下标压入队尾;
3、-1<3,-1 压入双端队列队尾保留到下一窗口进行比较;
4、3 为当前窗口的最大值;
5、窗口移动,-3 与队尾数据逐个比较,-3<-1,-3 压入双端队列队尾保留;
6、3 为当前窗口的最大值;
7、窗口继续移动,5>-3,-3 从双端队列队尾弹出;
8、5>-1,-1 从队尾弹出;
9、3 超出当前窗口,从队列头部弹出;
10、5 压入队列头部,成为当前窗口最大值;
11、继续移动窗口,操作与上述同理。
窗口最大值只需读取双端队列头部元素。
以上来自苏勇老师。
要分清头和尾
演绎维护单调双端队列的4个步骤
一四个步骤的目的,保证滑动窗口头部是最大值
(头,尾,尾,头)
第一步,头部出队,清理超范围(头部出队只出一个元素)
第二步,篮球队清理,移除尾部,在当前值前面的还小于当前值的元素
第三步,尾部入队,尾部范围正确
第四步,返回头部一一当前窗口最大值
比如【1 3 -1 -3 5 3 6 7】
先进入1,扫描3,发现3>1,然后1出队,3进队。-1<3,-1进队,最大值为3;
-3<-1, -3进队,返回头部,最大值为3;
清除头部3,5>-3, -3出队, 5>-1, -1出队,5进队,返回头部,最大值为5;
清除头部空格,3<5, 3进队,返回头部最大值为5;
清除头部空格,,扫描6,6>3, 3出队,6>5, 5出队,返回头部最大值为6;
清除头部空格,7>6,6出队,7入队,返回头部最大值7;
最后结果为335567;
以上自己理解