C++算法:优先级队列

优先级队列

1.最后一块石头的重量

使用优先级队列模拟即可。

cpp 复制代码
class Solution {
public:
    int lastStoneWeight(vector<int>& stones)
    {
        priority_queue<int> pq;
        for (int& e : stones)
            pq.push(e);
        while (pq.size() > 1)
        {
            int x = pq.top();
            pq.pop();
            int y = pq.top();
            pq.pop();
            if (x > y)
                pq.push(x - y);
        }
        return pq.size() ? pq.top() : 0;
    }
};

2. * TopK:数据流中的第K大元素

这道题其实就是TopK问题。TOP-K问题即求数据集合中前K个或第K大最大的元素或者最小的元素,一般情况下数据量都比较大。如果数据量大,不能使用排序解决,因为可能数据不能一次全部加载到内存,排序算法的空间消耗也会很大。

往往是用堆来解决TopK问题。求第K大的元素,创建小堆,控制堆的大小不超过K,把数据集合的元素入堆。当堆的大小为K时,新元素入堆,此时堆的大小为K+1,堆顶元素是这K+1个元素中最小的,即目前第K+1大的元素,此时pop,堆顶元素就是目前第K大的元素。如此遍历数据集合,就能得到前K个最大元素,堆顶为第K大元素。时间复杂度为O(N*logK)。

cpp 复制代码
class KthLargest {
    priority_queue<int, vector<int>, greater<int>> heap;
    int _k;
public:
    KthLargest(int k, vector<int>& nums)
    {
        _k = k;
        for (int e : nums)
        {
            heap.push(e);
            if (heap.size() > _k)
                heap.pop();
        }
    }

    int add(int val)
    {
        heap.push(val);
        if (heap.size() > _k)
            heap.pop();
        return heap.top();
    }
};

3. * TopK:前K个高频单词

用unordered_map或map统计单词出现频次;创建大小为k的堆,频次不同时满足小根堆,频次相同时,按照字典序,应满足大根堆;得到符合要求的前k个单词后,堆顶元素是频次小,字典序大,所以应该从ret数组尾部开始放元素,否则从头开始放元素后逆置数组。

cpp 复制代码
class Solution
{
    typedef pair<string, int> PSI;
    struct Greater
    {
        bool operator()(const PSI& p1, const PSI& p2)
        {
            if (p1.second == p2.second)
                return p1.first < p2.first;
            return p1.second > p2.second;
        }
    };
public:
    vector<string> topKFrequent(vector<string>& words, int k)
    {
        //统计单词频次
        map<string, int> m;
        for (string& e : words)
            m[e]++;
        
        //TopK
        priority_queue<PSI, vector<PSI>, Greater> heap;
        for (const PSI& psi : m)
        {
            heap.push(psi);
            if (heap.size() > k)
                heap.pop();
        }
        
        //提取结果
        vector<string> ret(k);
        for (int i = k - 1;i >= 0;i--)
        {
            ret[i] = heap.top().first;
            heap.pop();
        }
        return ret;
    }
};

4.数据流的中位数

利用大小堆解决。假设数据有序,数据中位数左边用大根堆left维护,右边用小根堆right维护。

如果m == n,则中位数为(left.top()+right.top())/2;如果m>n,即m == n+1,则中位数为left.top()。

每次add()时,对于新加入的数据num,如果m == n,当m为0或num<=left.top()时,直接进left;当num>left.top()时,num进right,此时m<n,再把right.top()放入left中,保持m == n。

如果m>n,当num>=left.top()时,则num直接进right;当num<left.top()时,num进left,此时m == n+2,再把left.top()放入right中保持 m == n+1。

cpp 复制代码
class MedianFinder
{
    priority_queue<int, vector<int>, less<int>> left;
    priority_queue<int, vector<int>, greater<int>> right;
public:
    MedianFinder()
    {
    }

    void addNum(int num)
    {
        int m = left.size(), n = right.size();

        if (m == n)
        {
            if (m == 0 || num <= left.top())
                left.push(num);
            else
            {
                right.push(num);
                left.push(right.top());
                right.pop();
            }
        }
        else
        {
            if (num < left.top())
            {
                left.push(num);
                right.push(left.top());
                left.pop();
            }
            else
                right.push(num);
        }
    }

    double findMedian()
    {
        int m = left.size(), n = right.size();
        if (m != n)
            return left.top();
        else
            return (left.top() + right.top()) / 2.0;
    }
};
相关推荐
骊城英雄10 小时前
Rust从入门到精通-trait
人工智能·算法·rust
狗凯之家源码网10 小时前
短剧系统搭建实战:源码功能与商业变现效果全景展示
开发语言·php
可编程芯片开发10 小时前
基于PI控制算法的pwm直流电机控制系统Simulink建模与仿真
算法
小王C语言10 小时前
【8.进行接口测试】:通过 curl 进行接口自动化测试 / 通过 python 程序进行接口自动化测试
网络·c++
怕浪猫11 小时前
2840亿参数只卖白菜价:DeepSeek V4 Flash 正式版上线,Agent 能力暴涨6倍
人工智能·算法
让学习成为一种生活方式11 小时前
苄基异喹啉生物碱糖基转移酶UGT74AN1晶体--Journal of Agricultural and Food Chemistry
人工智能·算法
alphaTao11 小时前
LeetCode 每日一题 2026/7/27-2026/8/2
python·算法·leetcode
易筋紫容11 小时前
创建型模式:对象的诞生艺术
开发语言·前端·javascript
888CC++11 小时前
C++ 快速学习指南:从入门到进阶的实战路线
开发语言·c++
2501_9269783311 小时前
提示工程的实战报告(二):模型的失败模式与边界行为
人工智能·深度学习·算法