Problems: https://leetcode.com/problems/sliding-window-maximum/
Solution:
利用deque,deque peek存储当前window内最大的值,实现的方法为:
- 当添加新unit时检查val,如果大于当前queue内的val,则将原unit pop出来,然后再加入新的unit
- 当添加的unit小于原来的val,则直接加入deque(因为该值有可能成为后面windows的最大值)
- 加入新unit的同时检查deque peek unit的index,如果超出window内的index则将该unit pop出来
class Solution {
// 将index和value绑定,便于后面检查最大值是否out of window
class Unit {
int val;
int idx;
public Unit(int value, int index) {
this.val = value;
this.idx = index;
}
}
public int[] maxSlidingWindow(int[] nums, int k) {
// 利用deque
Deque<Unit> queue = new LinkedList<>();
int count = 0;
int len = nums.length;
int[] ans = new int[len-k+1];
if(nums.length == 0) {
return nums;
}
for(int i=0; i<len; i++) {
int cur = nums[i];
// 如果此处count <= k的话,当count == k时,deque peek存的是前四个数的最大值
if(count < k) {
// 加入的值如果大于peek,则取代原来的成为新peek
while(!queue.isEmpty() && queue.getLast().val < cur) {
queue.pollLast();
}
queue.offerLast(new Unit(cur, i));
count++;
if(count == k) {
ans[0] = queue.getFirst().val;
}
} else {
// 加入的值如果大于peek,则原来的需要被pop出来
// 不管这个peek是不是valid,当更大的值出现时,原来小的值一定无效
while(!queue.isEmpty() && queue.getLast().val < cur) {
queue.pollLast();
}
// 要检查peek的index是否在window内
if(!queue.isEmpty() && queue.getFirst().idx <= i-k) {
queue.pollFirst();
}
queue.offerLast(new Unit(cur, i));
ans[i-k+1] = queue.getFirst().val;
}
}
return ans;
}
}
TC: O(n)
SC: O(n)
Reference: https://www.youtube.com/watch?v=uvsRkNiL0e0