LC-239.滑动窗口最大值
题目描述
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例1:
1 |
|
提示1:
1 |
|
单调队列
我们可以用单调队列存储窗口内的元素及其下标,从队首到队尾元素单调递减。那么对于每个窗口的最大值,取队首元素即可。
具体来说,我们每次将右指针后移一位时,将右指针新指向的元素尝试插入队尾,但为了保证队列的单调性,需要不断从队尾弹出元素直到队尾元素大于当前右指针元素,容易发现已经弹出的元素无需重新入队,这是因为这些元素均小于当前右指针元素且都是在其左侧的,也就是说这些元素会更早的离开窗口且更小。而对于移除左指针前一个指向的元素,我们把该操作延后处理,只需要在每次弹出队首元素时,校验其下标合法性即可,如果已经离开窗口则继续弹出队首元素直到遇到一个窗口内的下标。
每个元素最多只会进队一次出队一次,所以时间复杂度为 $O(N)$ 。
1 |
|
优先队列/TreeMap
类似的做法还有优先队列和 $TreeMap$ 。
1 |
|
1 |
|
线段树
对于区间查询,也可以使用线段树实现,只需要使用数组元素构建线段树后再查询每个窗口的最大值即可。时间复杂度为 $O(NLogN)$。
1 |
|
LC-239.滑动窗口最大值
https://wecgwm.github.io/2023/02/18/LC-239-滑动窗口最大值/