滑动窗口最大值⚓︎
描述⚓︎
详见中文题目链接。
解答⚓︎
单调队列是队尾既可以进队也可以出队、队头可以出队的队列 (目的是维护子序列的单调性)。维护最大值就是维护滑动窗口内的降序子序列。
注意:
- 队尾出队的条件:队列不空且新元素更优,则队中旧元素从队尾出队;
- 每个元素必然从队尾进队一次;
- 队头出队的条件:队中元素滑出了窗口;
- 队列中存储元素的下标(而不是数组中的元素),方便判断队头出队。
代码for
循环内的步骤:
- 解决队首已经出窗口的问题;
- 解决队尾与当前元素
a[i]
不满足单调性的问题; - 将当前元素下标加入队尾;
- 如果满足条件则输出结果。
以上步骤需要注意的细节:
- 上面四个步骤中一定要先3后4,因为有可能输出的正是新加入的那个元素;
- 队列中存的是原数组的下标,取值时要再套一层,
a[q[]]
; - 算最大值前注意将
hh
和tt
重置; hh
从0
开始,则数组下标也要从0
开始。
关于初始化的注意:
hh
和tt
的初始化是与数组第一个值下标有关的:hh
小于等于数组第一个下标(如数组下标从0
开始,hh <= 0
;数组下标从1
开始,hh <= 1
,可以是1
、0
、-1
等等);- 对于数组第一个值下标从
0
还是从1
开始,还会影响输出时的if
判断,需要对应修改: - 若下标从
0
开始,就是i >= k - 1
,因为第一个窗口为0 1 2
; - 若下标从
1
开始,就是i >= k
,因为首个窗口是1 2 3
; - 初始化时
hh
和tt
之间要间隔一个位,即hh == tt + 1
。