代码随想录算法训练营第13天| 239. 滑动窗口最大值 347.前 K 个高频元素

  • 今日学习的文章链接,或者视频链接

第五章 栈与队列part03

  • 自己看到题目的第一想法

  • 看完代码随想录之后的想法

239:

class MonotonicQueue {
    private:
        deque q;
    public:
        void push(int n) {
            // 将小于 n 的元素全部删除
            while (!q.empty() && q.back() < n) {
                q.pop_back();
            }
            // 然后将 n 加入尾部
            q.push_back(n);
        }

        int max() {
            return q.front();
        }

        void pop(int n) {
            if (!q.empty() && n == q.front()) {
                q.pop_front();
            }
        }
};
class Solution {
public:
    vector maxSlidingWindow(vector& nums, int k) {
        MonotonicQueue window;
        vector res;

        for (int i = 0; i < nums.size(); i++) {
            if (i -k+1< 0) {
                //先填满窗口的前 k - 1
                window.push(nums[i]);
            } 
            else if(i -k+1== 0)
            {
                window.push(nums[i]);
                res.push_back(window.max());
            }
            else 
            {
                // 窗口向前滑动,加入新数字
                window.push(nums[i]);
                // 移出旧数字
                window.pop(nums[i - k]);
                // 记录当前窗口的最大值
                res.push_back(window.max());
            }
        }

        return res;
    }
};

347:

class Solution {
public:
    // 小顶堆
    class mycomparison {
    public:
        bool operator()(const pair& lhs, const pair& rhs) {
            return lhs.second > rhs.second;
        }
    };
    vector topKFrequent(vector& nums, int k) {
        // 要统计元素出现频率
        unordered_map map; // map
        for (int i = 0; i < nums.size(); i++) {
            map[nums[i]]++;
        }
        // 对频率排序
        // 定义一个小顶堆,大小为k
        priority_queue, vector>, mycomparison> pri_que;

        // 用固定大小为k的小顶堆,扫面所有频率的数值
        for (unordered_map::iterator it = map.begin(); it != map.end(); it++) {
            pri_que.push(*it);
            if (pri_que.size() > k) { // 如果堆的大小大于了K,则队列弹出,保证堆的大小一直为k
                pri_que.pop();
            }
        }

        // 找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒序来输出到数组
        vector result(k);
        for (int i = k - 1; i >= 0; i--) {
            result[i] = pri_que.top().first;
            pri_que.pop();
        }
        return result;
    }
};

  • 自己实现过程中遇到哪些困难

  • 今日收获,记录一下自己的学习时长

大小顶堆的c++实现还是需要多写一写,

左>右,小顶堆

左<右,大顶堆

你可能感兴趣的:(算法,leetcode,数据结构)