代码随想录Day13:滑动窗口最大值、前 K 个高频元素

主要学习队列的一些经典用法。

滑动窗口最大值

题目有难度,单调队列的思路很重要,要多看视频复习

class Solution {
private:
    class MyQueue{
    public:
        deque<int> que;
        void popVal(int val){
            if(!que.empty() && val == que.front())
            {
                que.pop_front();
            }
        }

        void pushVal(int val){
            while(!que.empty() && val > que.back()){
                que.pop_back();
            }
            que.push_back(val);
        }

        int getMax(){
            return que.front();
        }
    };

public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        MyQueue que;
        vector<int> res;
        for(int i = 0; i < k; i++)
        {
            que.pushVal(nums[i]);
        }
        res.push_back(que.getMax());
        for(int i = k; i < nums.size(); i++)
        {
            que.popVal(nums[i-k]);
            que.pushVal(nums[i]);
            res.push_back(que.getMax());
        }
        return res;
    }
};

前 K 个高频元素

这部分有一些新的知识点,比如优先级队列自定义比较器

优先级队列:

优先级队列是一种特殊的队列,它比常规队列多了一个特性,即每个元素都有一定的优先级,数据项的出队顺序是按照每个元素的优先级权重进行的,而不是严格的先进先出(FIFO)规则。

优先级队列的常见应用包括:CPU任务调度,图形的广度优先搜索中用于维护顶点的访问次序等。

在C++ STL库中,优先级队列被定义为一种容器适配器,可以使用任何底层容器模型,比如一个向量或者一个 deque,来创建一个优先级队列。下面是一个最简单的优先级队列的定义示例:

#include <queue>
std::priority_queue<int> pq;

这段代码定义了一个存放int类型的优先级队列,比较函数是less,所以这是一个最大元素堆。队列中元素最大的元素在堆的顶部,每次出队都会弹出当前堆中最大的元素。
也可以自定义优先级队列中的比较规则,例如:

struct Compare {
    bool operator()(const int& a, const int& b) {
        return a > b;
    }
};
std::priority_queue<int, std::vector<int>, Compare> pq;

这里我们定义了一个比较函数对象,使得优先级队列成为最小元素堆。在这个优先级队列中,大小关系是由我们自定义的 Compare 操作符决定的,小的元素优先级更高。所以这个优先级队列每次会优先弹出最小的元素。

自定义比较器:

在定义比较函数对象时,这个函数意味着当operator()返回true时,第一个参数应该被视为优先级较低的元素。

所以如果我们有bool operator()(const int& a, const int& b) { return a > b; },这个函数在 a > b(即ab大)时返回true。这意味着当ab大的时候,a应该被视为优先级较低。这就建立了一个最小元素堆。

所以,如果你想要的是最大元素堆,那你的比较函数对象应该像这样:

struct Compare {
    bool operator()(const int& a, const int& b) {
        return a < b;
    }
}; 

这样当a小于b的时候,a会被视为优先级较低的元素,因此大的元素b(优先级高的)会先被弹出,这就成了一个最大元素堆。

题目实现代码:

class Solution {
public:
    class mycomparison{
    public:
        bool operator()(const pair<int, int>& lhs, const pair<int, int>& rhs){
            return lhs.second > rhs.second;
        }
    };
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int, int> myMap;
        for(int i = 0; i < nums.size(); i++)
        {
            myMap[nums[i]]++;
        }
        priority_queue<pair<int, int>, vector<pair<int, int>>, mycomparison> my_pri;

        for(unordered_map<int, int>::iterator it = myMap.begin(); it != myMap.end(); it++)
        {
            my_pri.push(*it);
            if(my_pri.size() > k)
            {
                my_pri.pop();
            }
        }
        vector<int> result(k);
        for(int i = k-1; i >=0; i--)
        {
            result[i] = my_pri.top().first;
            my_pri.pop();
        }
        return result;
    }
};
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值