关键要知道双端队列(双向队列)的特性
解题思路以及代码
package com.cn.dl.leetcode.stack;
import java.util.Arrays;
import java.util.LinkedList;
/**
* Created by yanshao on 2020-05-06.
*/
public class MaxSlidingWindow {
public int[] maxSlidingWindow(int[] nums, int k) {
/*
* 当前满足下面3个条件其中一个,都返回空数组
* */
if(nums == null || k < 1 ||nums.length < k){
return new int[]{};
}
/*
* 如果k=1,返回原始数组
* */
if(k == 1){
return nums;
}
/*
* 定义双向队列,记录最大元素的下标,优点:方便获取头节点、尾节点
* */
LinkedList<Integer> maxNumIndexes = new LinkedList<>();
/*
* 最终数组的个数:跟原始数组长度、k之间的关系
* numsLength=3,k=3,resLength=1
* numsLength=4,k=3,resLength=2
* numsLength=5,k=3,resLength=3
* numsLength=6,k=3,resLength=4
* numsLength=7,k=3,resLength=5
* numsLength=8,k=3,resLength=6
* .....
* 根据以上数据,得出resLength = numsLength - k + 1
* */
int[] res = new int[nums.length - k + 1];
int index = 0;
for(int i=0;i<nums.length;i++){
/*
* 如果队列不为空,并且队列中尾节点的value<=nums[i],依次出队
* */
while (! maxNumIndexes.isEmpty() && nums[maxNumIndexes.peekLast()] <= nums[i]){
maxNumIndexes.pollLast();
}
//将当前下标记录在队尾
maxNumIndexes.addLast(i);
/*
* 如果队首的value == i - k,表示超出了滑动出口的范围,则队首出队
* */
if(maxNumIndexes.peekFirst() == i - k){
maxNumIndexes.pollFirst();
}
/*
* 当滑动窗口的length(说白了,就是i) >= k - 1时,记录最大值
* */
if(i >= k - 1){
res[index ++] = nums[maxNumIndexes.peekFirst()];
}
}
return res;
}
public static void main(String[] args) {
int[] nums = {1,3,-1,-3,1,3,6,7};
int k = 3;
System.out.println(Arrays.toString(new MaxSlidingWindow().maxSlidingWindow(nums,k)));
}
}