解法的关键在于维护一个单调递减的双向队列。从尾部推入元素时,不断比较队尾元素与新元素的大小,如果比新元素还小,则需要从尾部推出队尾元素,直到队尾元素比新元素大或者队列直接空了,再把新元素推入。这样就可以保证这个队列中从头到尾的元素值一定是递减的。
而在窗口滑动过程中,从队列头部弹出所有由于移动导致已经不在窗口范围内的值即可。
代码如下:
const maxSlidingWindow = (nums, k) => {
if (!nums.length) {
return [];
}
const q = [];
// build the queue for first window
for(let i = 0; i < k; i++) {
while(q.length && nums[i] >= nums[q[q.length - 1]]) {
q.pop();
}
// it is the index of the element got pushed in here
q.push(i);
}
const answer = [nums[q[0]]];
for (let i = k; i < nums.length; i++) {
while(q.length && nums[i] >= nums[q[q.length - 1]]) {
q.pop();
}
q.push(i);
// remove all invalid indexes
while(q[0] <= i - k) {
q.shift();
}
// record the max value
answer.push(nums[q[0]]);
}
return answer;
};