239. 滑动窗口最大值 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/sliding-window-maximum/需要一个单调队列,这个队列的队头永远是最大的元素。窗口每往后移动一次,就将窗口中最左边的元素出队,最右边的下一个元素入队。
为了保持窗口中最大值永远在队头,需要定义这个队列的入队和出队规则:
入队:如果要入队的元素大于队尾元素,就把队尾元素移除,以保证越大的越靠近队头。例如队列本来是5,3,2,1现在4要入队,入队后队列就变成5,4。
出队:出队操作是为了让滑动窗口滑过的元素退出比较。如果要出队的元素就在队头,则移除它,否则说明它比队头小,之前就被移除过了,不需要进行任何操作。
此时滑动窗口最大值就是队头元素了。
class Solution {
static class MyQueue{
private Deque<Integer> deque = new LinkedList<>();
public void poll(int val){
if (!deque.isEmpty() && val==deque.peek()){
deque.poll();
}
}
public void push(int val){
while (!deque.isEmpty() && val>deque.getLast()){
deque.removeLast();
}
deque.add(val);
}
public int getMax(){
return deque.peek();
}
}
public static int[] maxSlidingWindow(int[] nums, int k) {
int[] res = new int[nums.length - k + 1];
MyQueue myQueue = new MyQueue();
for (int i=0;i<k;i++){
myQueue.push(nums[i]);
}
int n = 0;
res[n++] = myQueue.getMax();
for (int i=k;i<nums.length;i++){
myQueue.poll(nums[i-k]);
myQueue.push(nums[i]);
res[n++] = myQueue.getMax();
}
return res;
}
}