239.滑动窗口最大值
题目描述:
给出一个整数数组 $nums$ ,有一个大小为 $k$ 的滑动窗口从最左侧移动到最右侧。返回滑动窗口中的最大值。
数据范围:
$1\le n \le 10^5, 1\le k \le n$
题解:
使用单调队列,单调队列需要使用双端队列。因为求最大值,所以维护一个单调减的队列,里面放元素的下标。
当前要加入第 $i$ 个元素,加入之后的情形为 $(q[hh], \cdots,i)$ ,此时队列的大小为 $i - q[hh] + 1$ ,如果 $i - q[hh] + 1 > k$ ,说明加入之后超过了窗口大小,所以在加入之前需要弹出队首过期元素。也可以判断当前容量是不是已经达到了 $k$ ,即 $q[tt] - q[hh] + 1 \ge k$ 。
1 | while(tt >= hh && q[tt] - q[hh] + 1 >= k) ++hh; |
同时对待加入的元素 $nums[i]$ 需要维护单调性,和队尾元素比较,如果队尾元素小则一直弹出队尾。
1 | while(tt >= hh && nums[i] >= nums[q[tt]]) --tt; |
然后才能加入 $i$ 到队列
1 | q[++tt] = i; |
使用数组实现双端队列,其中初始值 $hh = 0, tt = -1$ ,保证了 $q[hh],q[tt]$ 分别表示队首队尾。
代码:
1 | class Solution |