利用双端队列作为窗口
添加元素前 先删除所有比自己小的元素 再将自己添加在队尾 保证单调性
队列中存放元素的索引 而不是直接存元素 便于通过索引判断何时淘汰队首
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
//利用双端队列作为窗口
//添加元素前 先删除所有比自己小的元素 再将自己添加在队尾 保证单调性
//队列中存放元素的索引 而不是直接存元素 便于通过索引判断何时淘汰队首
int len = nums.length;
int[] maxWnd = new int[len - k + 1]; //记录每个窗口的最大值
//双端队列 便于操作队首与队尾
Deque<Integer> wnd = new ArrayDeque<>();
for(int i = 0 ; i < len; i++) {
//添加元素到队列中 若即将加入的元素 更大 则删除前一个元素 直到即将添加的元素不是最大或队列已清空 清空则说明当前元素是历史最大值
//移除较小的值 将更大的值添加在队首 保证单调性
while(!wnd.isEmpty() && nums[i] > nums[wnd.getLast()]) {
wnd.removeLast();
}
//将当前元素添加到队尾
//经过第一步的特殊处理后 可以保证单调性 要么紧邻比自己大的元素 要么是历史最大值清空了队列队尾即队首
wnd.addLast(i);
//出队 若队首元素已不在窗口中 则移除
if(i - wnd.getFirst() >= k) {
wnd.removeFirst();
}
//记录当前窗口的最大值
if(i >= k - 1) { //由于未进行初始化 第一个窗口成型才添加最大值
maxWnd[i - k + 1] = nums[wnd.getFirst()];
}
}
return maxWnd;
}
}