Sword59-I——滑动窗口的最大值
方法1——双端队列
- 思路:
- 使用双端队列保存滑动窗口元素,res保存窗口最大值
- 滑动窗口还未形成,或者双端队列中只有一个元素,直接将元素加入
- 当双端队列最后一个元素小于当前j位置的元素,移除双端队列最后一个元素
- 特殊情况与临界分析:无
- 终止条件:无
- 步骤:
- 定义res数组,保存滑动窗口所形成的最大结果,其中结果个数为nums.length - k + 1
- 数组长度非零校验
- 定义双端队列,保证其中元素顺序为递减
- for循环(滑动窗口不断向右移动)
- 参数:左边界从1-k开始、右边界right从0开始,直到右边界到达数组末尾,左右边界同时移动
- 当此次比较不是第一次比较时(即i不为0),若前一轮比较中的较大值是左边界,则在该轮比较中需要从双端队列中删除队首元素
- while循环
- 循环条件:双端队列非空,且队尾元素小于右边界
- 移除双端队列尾部元素,保持双端队列递减状态
- 将右边界元素加入双端队列尾部
- 当形成滑动窗口(i大于0),开始记录窗口最大值,即为双端队列首部
- 返回结果数组
public int[] maxSlidingWindow(int[] nums, int k) {
int[] res = new int[nums.length - k + 1];
if (nums.length == 0) {
return new int[0];
}
Deque<Integer> deque = new LinkedList<>();
for (int left = 1 - k, right = 0; right < nums.length; left++, right++) {
if (left > 0 && deque.peekFirst() == nums[left - 1]) {
deque.removeFirst();
}
while (!deque.isEmpty() && deque.peekLast() < nums[right]) {
deque.removeLast();
}
deque.addLast(nums[right]);
if (left >= 0) {
res[left] = deque.peekFirst();
}
}
return res;
}
