代码随想录day11 | 239.滑动窗口最大值 347.前K个高频元素

文章目录

    • 一、滑动窗口最大值
    • 二、前K个高频元素

一、滑动窗口最大值

代码随想录 单调队列讲解

239.滑动窗口最大值
代码随想录day11 | 239.滑动窗口最大值 347.前K个高频元素_第1张图片

使用单调队列实现,还是有点难度的,多在草稿纸上模拟一下,看这个单调队列是如何维护的。

pop(value):如果窗口移除的元素value等于单调队列的出口元素,那么队列弹出元素,否则不用任何操作
push(value):如果push的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到push元素的数值小于等于队列入口元素的数值为止

单调队列:

class MyQueue{
     private:
     deque<int> dq;
     public:
     void pop(int val)
     {
         if(!dq.empty() && val == dq.front())
         {
             dq.pop_front();
         }
     }
     void push(int val)
     {
         while(!dq.empty() && val > dq.back())
         {
             dq.pop_back()
         }
         dq.push_back(val);
     }
     int front()
     {
         return dq.front();
     }
 };

完整代码:

class Solution
{
private:
    class MyQueue
    {
    private:
        deque<int> dq;

    public:
        void pop(int val)
        {
            if (!dq.empty() && val == dq.front())
            {
                dq.pop_front();
            }
        }
        void push(int val)
        {
            while (!dq.empty() && val > dq.back())
            {
                dq.pop_back();
            }
            dq.push_back(val);
        }
        int front()
        {
            return dq.front();
        }
    };

public:
    vector<int> maxSlidingWindow(vector<int> &nums, int k)
    {
        vector<int> res;
        MyQueue q;
        for (int i = 0; i < k; i++)
        {
            q.push(nums[i]);
        }
        res.push_back(q.front());

        for (int i = k; i < nums.size(); i++)
        {
            q.pop(nums[i - k]);
            q.push(nums[i]);
            res.push_back(q.front());
        }
        return res;
    }
};

二、前K个高频元素

347.前K个高频元素

经典topk问题。

class Solution
{
public:
    class compare
    {
    public:
        // 排升序
        bool operator()(const pair<int, int> &e1, const pair<int, int> &e2)
        {
            return e1.second > e2.second;
        }
    };
    vector<int> topKFrequent(vector<int> &nums, int k)
    {
        vector<int> res(k);
        unordered_map<int, int> map;
        for (auto e : nums)
        {
            map[e]++;
        }

        // 定义一个小堆 默认是大堆-》给的是less -> e1 < e2
        priority_queue<pair<int, int>, vector<pair<int, int>>, compare> q;

        // 遍历扫描这个map
        for (auto it = map.begin(); it != map.end(); it++)
        {
            q.push(*it);
            if (q.size() > k)
            {
                q.pop();
            }
        }

        for (int i = k - 1; i >= 0; i--)
        {
            res[i] = q.top().first;
            q.pop();
        }
        return res;
    }
};

Lamuda表达式的写法
class Solution
{
public:
    vector<int> topKFrequent(vector<int> &nums, int k)
    {
        vector<int> res(k);
        unordered_map<int, int> map;
        for (auto e : nums)
        {
            map[e]++;
        }

        auto compare = [](const pair<int, int> &e1, const pair<int, int> &e2)
        {
            return e1.second > e2.second;
        };
        // 定义一个小堆
        priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(compare)> q(compare);

        // 遍历扫描这个map
        for (auto it = map.begin(); it != map.end(); it++)
        {
            q.push(*it);
            if (q.size() > k)
            {
                q.pop();
            }
        }

        for (int i = k - 1; i >= 0; i--)
        {
            res[i] = q.top().first;
            q.pop();
        }
        return res;
    }
};

你可能感兴趣的:(笔试强训,栈和队列,topk)