1、题目描述
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回滑动窗口中的最大值。
示例 1:
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置 最大值
--------------- -----
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7
2、题目分析
- 一个数组内维持一个向右滑动的窗口,每次返回窗口的最大值
- 首先考虑用传统的输入每次都要判断当前窗口的最大值的遍历方法 结果超时
- 维持一个双向队列,存储的是数组的下标,使用下标的原因是遍历的时候有些元素会过时
- 当前窗口的最大值存储在队列的头部,当前加入元素的比尾部元素大时,尾部坐标出列
- 直到当前元素小于尾部元素的大小,当前的元素下标入列
- 此时需要判断头部元素在当前的窗口有没有过时
- 用一个数组存储结果,窗口开始滑动的时候就开始记录结果
3、代码实现
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int[] res = new int[nums.length - k + 1];
Deque<Integer> deque = new LinkedList<>();
for(int i = 0;i < nums.length;i++){
while(!deque.isEmpty() && nums[i] >= nums[deque.peekLast()])
deque.pollLast();
deque.addLast(i);
if(deque.peek() <= i - k)
deque.pollFirst();
if(i - k + 1 >= 0)
res[i - k + 1] = nums[deque.peekFirst()];
}
return res;
}
}
4、复杂度分析
- 时间复杂度:O(N),N是输入数组的大小
- 空间复杂度:O(K),K是输入K的大小