使用优先队列priority_queue实现对基unordered_map于value值的数值筛选

众所周知,map结构可以基于key值默认从小到大的排序,但是unordered_map对数据的处理方式比map更快和更便捷。

做题时,基于key我们可以将unordered_map换成map,但是有时候我们不得不于value值的排序

比如下面这个题目:

347. 前 K 个高频元素 - 力扣(LeetCode)

 首先第一想法肯定是使用哈希表存储每一个元素出现的次数,为了拿到前k个优先元素,排序成了一个大问题

避坑经验:

unordered_map不能使用sort进行自定义排序,这是在官方文档里面有说明的;

所以要使用堆、也就是优先队列

堆分为大顶堆和小顶堆,大顶堆就是将队列里面最大的元素放在队首,而小顶堆就是将队列里面最小的元素放在队首。堆的声明默认是一个大顶堆,我们可以很轻易的拿到队列当作最大的元素。

至于队列的顺序,堆只是将最值放在队首,并不会对队列严格排序;

扫描二维码关注公众号,回复: 14797026 查看本文章

声明一个大顶堆:需要引用头文件:#include<queue>

priority_queue<int> p;

对于基本数据类型(int, char等),声明小顶堆有自带的比较函数

priority_queue<int, vector<int>, greater<int> > q;

 对于priority_queue的参数列表:第一个是数据类型,第二个是存储类型的container容器,一般是vector<typename>,第三个则是比较函数,大顶堆的话后面两个参数可以省略。

greater<int>就是小顶堆的自带比较函数

但是对于像pair<int,int>(队组)这样的数据类型,priority_queue就没有自带比较函数了,不但需要自己写比较函数,声明上也有些许不同:

//比较函数

static bool cmp(pair<int,int>& a, pair<int,int>b){

        return a.second > b.second;

    }

//声明

priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(&cmp)> q(cmp);

其中的decltype函数是自动类型推断,可以将pair<int,int>等比较复杂的数据类型识别出来,但是要传入比较函数的地址

我们利用小顶堆不断的取出unordered_map里面的小元素,这样算是一层筛选,对于中等题,基本就可以过了。

接下来请看本题代码吧:

class Solution {
public:
    static bool cmp(pair<int,int>& a, pair<int,int>b){
        return a.second > b.second;
    }
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int,int>ump;
        int n = nums.size();
        vector<int>ans;
        for(int i = 0; i < nums.size(); i++){
            ump[nums[i]]++;
        }
        //创建一个pair类型的小顶堆
        priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(&cmp)> q(cmp);
        //decltype用于自动类型推断、将pair依照value值把最小的放在前面
        // a是nums[i]数值,b是此数值出现的次数
        for(auto& [a,b] : ump){
            if(q.size() == k){
                if(q.top().second < b){
                    q.pop();
                    q.emplace(a,b);
                }
            }
            else q.emplace(a,b);
        }
        while(q.size() != 0){
            ans.push_back(q.top().first);
            q.pop();
        }
        return ans;
    }
};

希望和诸君共勉!

猜你喜欢

转载自blog.csdn.net/qq_61567032/article/details/125862960