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;
    }
};
相关推荐
鹿角片ljp6 小时前
LeetCode 46. 全排列|吃透回溯
算法·leetcode·职场和发展
鼎艺创新科技6 小时前
不依赖 UE/Unity:我们如何从零搭建一套国产三维 GIS 渲染引擎
人工智能·算法·unity·游戏引擎·三维电子沙盘
剩下了什么6 小时前
float32 与 float64 精度陷阱:如何在 Go 中避免错误使用
开发语言·后端·golang
指尖时光.7 小时前
Three.js 超全入门综合案例
开发语言·javascript·ecmascript
暴力求解7 小时前
Linux网络---传输层协议TCP(二)
linux·服务器·开发语言·网络·tcp/ip
吴声子夜歌7 小时前
Java面试题——基础(一)
java·开发语言
别动我齐刘海8 小时前
机器人运动控制学习2——基础进阶
c++·人工智能·神经网络·学习·目标检测·机器学习·机器人
小庞在加油8 小时前
WinDbg实战:QT/跨平台项目死锁与无响应问题排查指南
开发语言·qt·windbg·工具
Vae_Mars8 小时前
C#中的delegate委托
开发语言·c#
傻啦嘿哟8 小时前
英雄联盟皮肤爬虫:爬取全皮肤价格与特效,做比价工具
java·c++·爬虫