給定一個數組 nums,有一個大小爲 k 的滑動窗口從數組的最左側移動到數組的最右側。你只可以看到在滑動窗口內的 k 個數字。滑動窗口每次只向右移動一位。
返回滑動窗口中的最大值。
示例:
輸入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
輸出: [3,3,5,5,6,7]
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
/**
* 滑動窗口最大值
*/
public class Solution {
public Solution() {
}
;
/**
* 遍歷,暴力法
* O(Nlogk)
* @param nums
* @param k
* @return
*/
public int[] maxSlidingWindow(int[] nums, int k) {
int n = nums.length;
if (n * k == 0) {
return new int[0];
}
int[] output = new int[n - k + 1];
for (int i = 0; i < n - k + 1; i++) {
int max = Integer.MIN_VALUE;
for (int j = i; j < i + k; j++) {
max = Math.max(max, nums[j]);
}
output[i] = max;
}
return output;
}
/**
* 雙端隊列
* 滑動窗口作爲雙端隊列
* O(N)
* @param nums
* @param k
* @return
*/
public int[] maxSlidingWindowDeque(int[] nums, int k) {
int n = nums.length;
if (n * k == 0) {
return new int[0];
}
int[] output = new int[n - k + 1];
Deque<Integer> window = new ArrayDeque<>();//也可以用數組模擬
for (int i = 0; i < n; i++) {
// 每次移動窗口時,窗口左邊的元素從隊列中刪除
if (i >= k && window.peek() <= i - k + 1) {
window.remove(0);
}
// 新入隊列元素,與隊列中元素遍歷比較,刪除小於nums[i] 的元素
while (!window.isEmpty() && nums[window.peekLast()] <= nums[i]) {
window.removeLast();
}
window.add(i);
// 隊列左側是最大值,加入結果
if (i - k + 1 >= 0) {
output[i - k + 1] = nums[window.peek()];
}
}
return output;
}
public static void main(String[] args) {
int[] aa = {3, 5, -1, 2, 8, 4};
Solution ob = new Solution();
int[] out = ob.maxSlidingWindowDeque(aa, 3);
System.out.println(Arrays.toString(out));
}
}