思路:
滑动窗口,使用双端队列作为滑动窗口
代码:
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums==null||k==0){
return new int[0];
}
//注意是Deque而不是Queue
Deque<Integer> deque=new LinkedList<>();
int[] res=new int[nums.length-k+1];
//未形成窗口
for(int i=0;i<k;i++){
while(!deque.isEmpty()&&deque.peekLast()<nums[i]){
//这里是removeLast而不是removeFirst
deque.removeLast();
}
deque.addLast(nums[i]);
}
//一定要初始化,把形成的第一个窗口的最大值放入
res[0]=deque.peekFirst();
//形成窗口后
for(int i=k;i<nums.length;i++){
//窗口向右滑动,要去掉最左边的值
if(deque.peekFirst()==nums[i-k]){
deque.removeFirst();
}
while(!deque.isEmpty()&&deque.peekLast()<nums[i]){
deque.removeLast();
}
deque.addLast(nums[i]);
res[i-k+1]=deque.peekFirst();
}
return res;
}
}
分解:
1)第一步要判空
2)创建双端队列,是Deque,new LinkedList
3)分为未形成窗口和形成窗口后2个循环
4)res[0]初始化一定要把第一个窗口的最大值传入
5)除了窗口向右滑动时要去掉最左边的值,其余情况都是把双端队列最右边的值去掉(是判断了队列最后一个值比要加入的值要小,将队尾的去掉,加入更大的值;如果是比队尾元素小,则直接加入)
这样就是把比当前要加入的值小的元素全部弹出
复杂度分析:
时间复杂度:O(N) 2个遍历总共遍历了N个元素
空间复杂度:O(K)双端队列中最多存储3个元素