算法笔记36:I. 滑动窗口的最大值

112 阅读1分钟

剑指 Offer 59 - I. 滑动窗口的最大值

解法的关键在于维护一个单调递减的双向队列。从尾部推入元素时,不断比较队尾元素与新元素的大小,如果比新元素还小,则需要从尾部推出队尾元素,直到队尾元素比新元素大或者队列直接空了,再把新元素推入。这样就可以保证这个队列中从头到尾的元素值一定是递减的。

而在窗口滑动过程中,从队列头部弹出所有由于移动导致已经不在窗口范围内的值即可。

代码如下:

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;
};