class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
MonotonicQueue window = new MonotonicQueue();
List<Integer> res = new ArrayList<>();
for (int i = 0; i < nums.length; i++) {
if (i < k-1) {
//先填满窗口的前 k - 1
window.push(nums[i]);
} else {
// 窗口右边界右移,加入新数字
window.push(nums[i]);
// 记录此时窗口最大值
res.add(window.max());
// 窗口左边界左移,删除旧数字
window.pop(nums[i-k+1]);
}
}
// 结果转换为数组
int [] arr = new int [res.size()];
for (int i = 0; i < res.size(); i++) {
arr[i] = res.get(i);
}
return arr;
}
}
// 单调队列数据结构
class MonotonicQueue {
// 双链表,支持头部和尾部增删元素
private LinkedList<Integer> q = new LinkedList<>();
// 操作1:向队列加入一个元素
public void push(int n) {
// 将前面小于自己的元素都删除
while (!q.isEmpty() && q.getLast() < n) {
q.pollLast(); // 移除队尾元素
}
q.addLast(n); // 加入队尾
}
// 操作2:返回队列中最大值
public int max() {
// 队头的元素肯定是最大的
return q.getFirst();
}
// 操作1:删除队列中指定元素
public void pop(int n) {
if (n == q.getFirst()) {
q.pollFirst();
}
}
}