优先队列自定义比较器

Posted

技术标签:

【中文标题】优先队列自定义比较器【英文标题】:Priority queue custom comparator 【发布时间】:2020-07-02 15:09:02 【问题描述】:

下面是从数组中获取前 K 个频繁元素的代码。代码是正确的,但我对比较器在这里做什么感到困惑。为什么它是“p1.second > p2.second”而不是“p1.second”。 second

class Solution 
struct compare 
    bool operator() (pair<int, int>p1, pair<int, int>p2) 
        return p1.second > p2.second;
    
;

公开: 向量 topKFrequent(vector& nums, int k)

    int n = nums.size();
    
    unordered_map<int, int>m;
    for (int i = 0; i < n; i++) 
        m[nums[i]]++;
    
    
    priority_queue<pair<int, int>, vector<pair<int, int>>, compare>pq;
    for (auto it = m.begin(); it != m.end(); it++) 
        pq.push(make_pair(it->first, it->second));
        if (pq.size() > k)
            pq.pop();
    
    
    vector<int>v;
    while (!pq.empty()) 
        pair<int, int>p = pq.top();
        v.push_back(p.first);
        pq.pop();
    
    
    return v;
**

;**

【问题讨论】:

计数较少的对不应该是堆顶的那个 为什么最低的会在顶部?队列的顶部是下一个要走的元素,应该是具有最高 priority 的元素 【参考方案1】:

默认情况下,std::priority_queue 使用std::less 比较器。在这种情况下,pop() 会删除 最大的 元素。

但是,在您的情况下,您希望将 k 保留在队列中的最大元素,并将 pop() 最小 一个(丢弃它)。为此,您需要反转比较的意义。

【讨论】:

【参考方案2】:

优先级队列的作用是在容器上构建一个堆,容器的尾部是堆的顶部,&gt;表示降序排列,使频率最低的元素成为顶部并首先弹出。

【讨论】:

【参考方案3】:

当我们想以自定义方式构建堆时,比较器函数作为参数传递。堆的一个节点存储两个值,即元素及其频率。由于您使用的是 pair,这意味着该对的第一个值是元素本身,第二个值是它的频率。 现在,在比较器函数中,您只需根据它们的第二个值比较两个 pair,即第二个值较大的应该先出现。因此,它根据频率存储堆元素。

【讨论】:

以上是关于优先队列自定义比较器的主要内容,如果未能解决你的问题,请参考以下文章

优先队列自定义比较器

使用自定义比较器声明 C++ 优先级队列的问题

将自定义比较器传递到 Cython 中的优先级队列

JAVA比较器的写法和优先队列的使用

JAVA比较器的写法和优先队列的使用

具有自定义比较功能的 C++ 优先级队列在 Push() 上行为不正确