题解:
双端队列是一种特殊的队列,允许你在队列的两端进行插入和删除操作。在滑动窗口问题中,我们使用它来存储可能是当前窗口最大值的元素的索引。
维护队列的顺序:
- 当新元素进入窗口时,我们将它与队列尾部的元素进行比较。
- 如果新元素更大,那么队列尾部的元素就不可能再成为窗口的最大值了,所以我们将它们从队列中移除。
- 我们重复这个过程,直到队列为空,或者队列尾部的元素比新元素大。
- 这样可以确保队列是按照元素值递减的顺序排列的。
保证队列中元素在窗口内:
- 我们需要确保队列中的元素都在当前窗口内。
- 如果队列头部的元素(当前最大值)已经不在窗口内(即它的索引小于当前窗口的起始索引),我们就将它从队列头部移除。
获取当前窗口的最大值:
- 由于队列是递减排序的,队列头部的元素就是当前窗口的最大值。
- 一旦窗口大小达到 k,我们就可以将队列头部的元素作为当前窗口的最大值记录下来。
代码如下:
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums == null || k < 1 || nums.length < k) {
return null;
}
// qmax 窗口最大值的更新结构
// 放下标
LinkedList<Integer> qmax = new LinkedList<>();
int[] res = new int[nums.length - k + 1];
int index = 0;
for (int R = 0; R < nums.length; R++) {
while (!qmax.isEmpty() && nums[qmax.peekLast()] <= nums[R]) {
qmax.pollLast();
}
qmax.addLast(R);
if (qmax.peekFirst() == R - k) {
qmax.pollFirst();
}
if (R >= k - 1) {
res[index++] = nums[qmax.peekFirst()];
}
}
return res;
}
}