關鍵要知道雙端隊列(雙向隊列)的特性
解題思路以及代碼
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)));
}
}