代码随想录算法训练营第13天 【栈与队列③】| 239. 滑动窗口最大值

44 阅读1分钟

今天两个题目整体难度都更大,使用队列时,一般会考虑优先级队列单调队列

239. 滑动窗口最大值

单调队列(前面的数字不可能比后面的数字还小),有思路,但要注意细节!!!

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number[]}
 */
var maxSlidingWindow = function(nums, k) {
    // 构造一个单调队列
    class MonoQueue {
        queue;
        constructor () {
            this.queue = [];
        }

        front() {
            return this.queue[0];
        }

        // 入队 会把前面小于新元素的旧元素给全部弹出
        enqueue(value) {
            // 队尾元素
            let back = this.queue[this.queue.length - 1];
            // 新元素大于之前的元素
            // 【注意】必须得写成 back !== undefined
            while (back !== undefined && value > back) {
                this.queue.pop();
                back = this.queue[this.queue.length - 1];
            }
            this.queue.push(value);
        }

        // 出队
        dequeue(value) {
            let front = this.front();
            if (value === front) {
                this.queue.shift();
            }
        }

    }

    let monoQueue = new MonoQueue();
    // 结果数组
    let resArr = [];
    let i = 0, j = 0;

    // 让一个k窗口内的元素先进来
    while (j < k) {
        monoQueue.enqueue(nums[j]);
        j++;
    }
    resArr.push(monoQueue.front());

    // 遍历完 nums 剩下的元素
    while (j < nums.length) {
        monoQueue.enqueue(nums[j]);
        monoQueue.dequeue(nums[i]);
        resArr.push(monoQueue.front());
        j++;
        i++;
    }

    return resArr;
};

347. 前 K 个高频元素

难点是:优先级队列(小顶堆)的数据结构与api

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number[]}
 */
var topKFrequent = function(nums, k) {
    const map = new Map();
    const res = [];
    // 统计频次
    for (const n of nums) {
        map.set(n, (map.get(n) || 0) + 1)
    }
    //先创建一个小顶堆
    const heap = new PriorityQueue({
        compare: (a, b) => a.value - b.value
    }) 
    // 频次排序
    for (const [key, value] of map) {
        heap.enqueue({key, value});
        if (heap.size() > k) {
            heap.dequeue();
        }
    }
    // 输出结果答案
    while (heap.size()) {
        res.push(heap.dequeue().key);
    }

    return res;
};