题目链接
英文链接:https://leetcode.com/problems/sliding-window-maximum/
中文链接:https://leetcode-cn.com/problems/sliding-window-maximum/
题目详述
给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口 k 内的数字。滑动窗口每次只向右移动一位。
返回滑动窗口最大值。
示例:
1 | 输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3 |
注意:
你可以假设 k 总是有效的,1 ≤ k ≤ 输入数组的大小,且输入数组不为空。
进阶:
你能在线性时间复杂度内解决此题吗?
题目详解
方法一:构建一个大顶堆,维护堆的大小为 k,时间复杂度为 O(nlogk)。代码略。
方法二:运用单调队列。时间复杂度为 O(n)。
- 构建一个双端队列,队列里面元素从队首到队尾是严格按从大到小排序的。
- 每加入一个元素之前,判断加入元素后队列是否满足单调性。
- 若满足直接加入。
- 若不满足,不断弹出队尾元素直至满足单调性后再加入。
- 然后检查是否存在过期元素,若存在则删除。
- 单调队列的队首元素永远是滑动窗口的最大值。
1 | public class LeetCode_00239 { |
方法三:利用窗口的传播性。时间复杂度为 O(n)。
- 构建两个数组 left 和 right。
- left 数组每个大小为 k 的窗口从左往右传播。
- right 数组每个大小为 k 的窗口从右往左传播。
- 则每个窗口的当前最大值为
max{right[i], left[i + k - 1]}
。
1 | public class LeetCode_00239 { |