思路为寻找最大值,那么每新加入一个值,前面比这个值小的都不需要。那么每新加入一个值,从队尾入列前,与前面的值比较,比它小的就删掉,直到遇到比它大的或者成为队首。这样队列也是从大到小的排列。
从队尾插入,队首为当前窗口最大值:
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int n = nums.length;
if(n==0) return new int[0];
int []result = new int[n-k+1];
int ri = 0;
Deque<Integer> deque = new ArrayDeque<>();//创建双端队列
for(int i = 0;i < n;i++){
//判断队首元素的索引值是否在窗口内,如果不在,删除它
//deque.peek()返回队列的队首元素
while(!deque.isEmpty() && deque.peek()<i-k+1){
deque.poll();
}
//判断队尾元素与新入列的元素大小,如果新元素大,则删除队尾元素
//一直到队列为空或者队尾元素大于新入列的元素
//此时队列的顺序为从队尾到队首,从小到大
//即新元素入列后,它的前方不会有比他更小的元素存在
while((!deque.isEmpty() && nums[i] >= nums[deque.peekLast()])){
deque.pollLast();
}
deque.offer(i);
//将队首元素索引对应的nums值赋给result
if(i >= k-1){
result[ri++] = nums[deque.peek()];
}
}
return result;
}
}
同理可得
从队首插入,队尾为当前最大值
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int n = nums.length;
if (n == 0) return new int[0];
int []result = new int[n-k+1];
Deque<Integer> deque = new ArrayDeque<>();
int r = 0;
for(int i = 0;i < n;i++){
while(!deque.isEmpty() && deque.peekLast()<i-k+1){
deque.pollLast();
}
while(!deque.isEmpty() && nums[i] >= nums[deque.peek()]){
deque.poll();
}
deque.offerFirst(i);
if(i>=k-1){
result[r++] = nums[deque.peekLast()];
}
}
return result;
}
}