【LeetCode热题100】优先级队列

news2025/1/16 2:51:55

这盘博客记录了关于优先级队列的几道题,包括最后一块石头的重量、数据流中的第K大元素、前K个高频单词、数据流的中位数。

class Solution {
public:
    int lastStoneWeight(vector<int>& stones) 
    {
        priority_queue<int> heap;
        for(auto s : stones) heap.push(s);
        while(heap.size() > 1)
        {
            int x = heap.top();heap.pop();
            int y = heap.top();heap.pop();
            if(x > y) heap.push(x-y);
        }
        return heap.size() ? heap.top():0;
    }
};

思路分析:这道题先要创建一个大根堆,将所给数组中的每一个值放入大根堆,堆顶的就是重量最大的,依次得到两个堆顶的元素,将它们相减,如果相减后不为0,那么将差值放到堆里。再次取两次堆顶的元素,重复上述过程,直到堆里元素个数≤1。

class KthLargest {
    priority_queue<int, vector<int>, greater<int>> _p;
    int _k;
public:
    KthLargest(int k, vector<int>& nums):_k(k) 
    {
        for(auto e : nums)
        {
            _p.push(e);
            if(_p.size() > _k) _p.pop();
        }
    }
    int add(int val) 
    {
        _p.push(val);
        if(_p.size() > _k) _p.pop();
        return _p.top();
    }
};

题目分析:这道题是要得到数据流中的第K大元素,也就是和TopK问题相关,所以要建立一个大小为K的小堆。将数据流里的元素依次插入到小堆,在插入一个元素之后,堆顶元素就是第K大元素。

class Solution {
    using PSI = pair<string, int>;
public:
    struct cmp
    {
        bool operator()(const PSI& p1, const PSI& p2)
        {
            if(p1.second == p2.second) 
                return p1.first < p2.first; //频次相同,按照大根堆的方式排序
            return p1.second > p2.second;
        }
    };
    vector<string> topKFrequent(vector<string>& words, int k) 
    {
        //1.统计一下每个单词的频次
        unordered_map<string, int> hash;
        for(auto& e : words) hash[e]++;

        //2.创建一个大小为k的堆
        priority_queue<PSI, vector<PSI>, cmp> heap;

        //3.TopK的主逻辑
        for(auto e : hash)
        {
            heap.push(e);
            if(heap.size() > k) heap.pop(); 
        }
        
        //4.提取结果
        vector<string> ret(k);
        for(int i = k-1 ; i >=0 ; i--)
        {
            ret[i] = heap.top().first;
            heap.pop();
        }
        return ret;   
    }
};

题目分析:首先创建一个哈希表hash<string,int>,把单词列表中的每一个单词放到哈希表中。创建一个大小为k的堆,堆中的cmp方法先比较频次,频次相同则比较字母序。遍历这个哈希表,将哈希表中的元素依次这个放入堆里,最后得到的堆就是所要的K个,并将他们逆序放在一个vector里。

class MedianFinder 
{
private:
    priority_queue<int> _left;
    priority_queue<int, vector<int>, greater<int>> _right;
public:
    MedianFinder() {
        
    }
    
    void addNum(int num) 
    {
        if(_left.size() == _right.size())
        {
            if(_left.empty() || 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();
        int n = _right.size();
        if(m == n) return (_left.top() + _right.top())/2.0;
        else return _left.top();
    }
};

题目分析:这道题有三种思路:

1.直接sort,来一个值排序一次,sort的时间复杂度为O(nlogn),find时直接根据数组下标查找即可,为O(1)。但是这种方法会超时。

2.采用插入排序,每次进来插入一个数就进行插入,时间复杂度为O(N),find时也只需要根据数组下标查找,为O(1)。

3.大小堆来维护数据流的中位数,我们创建一个大堆_left和一个小堆_right,其大小分别是m和n,我们需要维护这样一个规则:m==n,或m=n+1。通过取两个堆的堆顶元素之和/2或_left堆顶元素,得到中位数。我们需要处理一个细节问题,就是在新数num来的时候,加到哪个堆上呢?这里需要分类讨论,,设x为_left栈顶元素:

1)m==n ,

        如果num <= x 或 m == 0,把num直接放到_left;如果num > x,把num先放到_right,然后把_right的top放到_left,_right栈顶元素出栈。

2)m=n+1

        如果num <= x,先把num放到_left,然后再把_left的top放到_right,_left的栈顶元素出栈;如果num > x,直接把num放到_right。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2250707.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

node.js基础学习-cheerio模块-简单小爬虫(五)

学习cheerio模块&#xff0c;简单做一个爬取图片网站的图片&#xff0c;并且将这些图片下载到本地指定的文件夹下&#xff0c;很多图片网站都有一些反爬取的机制&#xff0c;找的好几个都会报302错误&#xff0c;所以我找了一个小的图片网站&#xff0c;这个没有反爬取机制&…

技术创新与人才培养并重 软通动力子公司鸿湖万联亮相OpenHarmony人才生态大会

11月27日&#xff0c;由开放原子开源基金会指导&#xff0c;OpenHarmony项目群工作委员会主办的OpenHarmony人才生态大会2024在武汉隆重举办。软通动力子公司鸿湖万联作为OpenHarmony项目群A类捐赠人应邀出席。大会期间&#xff0c;鸿湖万联不仅深度参与了OpenHarmony人才生态年…

FFmpeg 推流给 FreeSWITCH

FFmpeg 推流&#xff0c;貌似不难&#xff0c;网上有很多资料, 接到一个任务&#xff0c;推流给 FreeSWITCH&#xff0c;最开始以为很容易&#xff0c; 实则不然&#xff0c;FreeSWITCH uuid_debug_media <uuid>&#xff0c; 一直没人任何反应 仔细一查&#xff0c;Fr…

彻底理解quadtree四叉树、Octree八叉树 —— 点云的空间划分的标准做法

1.参考文章&#xff1a; &#xff08;1&#xff09;https://www.zhihu.com/question/25111128 这里面的第一个回答&#xff0c;有一幅图&#xff1a; 只要理解的四叉树的构建&#xff0c;对于八叉树的构建原理类比方法完全一样&#xff1a;对于二维平面内的随机分布的这些点&…

【工具变量】上市公司企业数字化转型指数(甄红线版本,战略引领、技术驱动、环境支撑、数字化成果及应用)2011-2022年

一、测算方式&#xff1a;参考《经济研究》甄红线&#xff08;2023&#xff09;老师研究的做法&#xff0c;本文采用 &#xff23;&#xff33;&#xff2d;&#xff21;&#xff32; 数据库中国上市公司数字化转型研究数据库中企业数字化转型指数来衡量企业数字化转型水平。 数…

长短期记忆网络 (LSTM) 简介

文章目录 一、说明二、传统 RNN 的问题三、为什么梯度消失&#xff1f;四、长短期记忆网络简介五、忘记门六、Update Gate (Input Gate)七、Output Gate八、数学上的内存九、从 LSTM 到 Transformer十、总结 一、说明 机器学习取得进步的领域之一是自然语言处理。对于用于机器…

安卓悬浮窗应用外无法穿透事件问题

现象&#xff1a; 应用内悬浮窗如何设置了 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE在自己应用内事件穿透正常&#xff0c;但到应用外就无法点击。 原因&#xff1a; 解决方法&#xff1a; layoutParams.alpha 0.8f …

linux minio安装

安装minio&#xff08;Centos&#xff09; 1. 查看服务器版本uname -a 2. 到minio官网下载对应的版本 官网地址&#xff1a;minio官网下载 根据上面查看的信息是x86_64系统所以我们下载linu-amd64 3. 上传到服务器 新建minioServer目录 上传至该目录下 赋权 chmod x mi…

JavaScript字符串

这张图片主要介绍了JavaScript中的字符串类型&#xff08;string&#xff09;。 字符串 1. 字符串的定义 在JavaScript中&#xff0c;通过单引号&#xff08;&#xff09;、双引号&#xff08;"&#xff09;或反引号&#xff08;&#xff09;包裹的数据都叫字符串。单引…

Linq中的投影运算 (C#):Select、SelectMany、Zip

投影是指将对象转换为一种新形式的操作&#xff0c;该形式通常只包含那些将随后使用的属性。 通过使用投影&#xff0c;您可以构造从每个对象生成的新类型。 可以投影属性&#xff0c;并对该属性执行数学函数。 还可以在不更改原始对象的情况下投影该对象。 1、Select 下面的…

RabbitMQ在手动消费的模式下设置失败重新投递策略

最近在写RabbitMQ的消费者&#xff0c;因为业务需求&#xff0c;希望失败后重试一定次数&#xff0c;超过之后就不处理了&#xff0c;或者放入死信队列。我这里就达到重试次数后就不处理了。本来以为很简单的&#xff0c;问了kimi&#xff0c;按它的方法配置之后&#xff0c;发…

Maven install java heap space

Maven install java heap space 打包报错 Maven install java heap space 解决&#xff1a; vm option: -Xms1024m -Xmx1024m如果 vm配置了&#xff0c;还是一样报错&#xff0c;就重新选择JRE看看是否正确&#xff0c;idea会默认自己的环境&#xff0c;导致设置vm无效&…

OpenCV_Code_LOG

孔洞填充 void fillHole(const Mat srcBw, Mat &dstBw) {Size m_Size srcBw.size();Mat TempMat::zeros(m_Size.height2,m_Size.width2,srcBw.type());//延展图像srcBw.copyTo(Temp(Range(1, m_Size.height 1), Range(1, m_Size.width 1)));cv::floodFill(Temp, Point(…

C7.5【x86汇编】底层分析范围for的执行过程

目录 1.反汇编代码 2.分析 1.栈区初始化 2.设置数组元素的值 3. 逐条分析范围for 1.arr的地址被放到[ebp-2Ch]处 2.[ebp-2Ch]指向的值被复制一份到[ebp-30h]处 3.eax暂存[ebp-2Ch]指向的值,加28h后存储到[ebp-34h]处 4.跳转指令 5.比较[ebp-30h]和[ebp-34h]指向的值,…

hue 4.11容器化部署,已结合Hive与Hadoop

配合《Hue 部署过程中的报错处理》食用更佳 官方配置说明页面&#xff1a; https://docs.gethue.com/administrator/configuration/connectors/ 官方配置hue.ini页面 https://github.com/cloudera/hue/blob/master/desktop/conf.dist/hue.ini docker部署 注意&#xff1a; …

51单片机快速入门之中断的应用 2024/11/23 串口中断

51单片机快速入门之中断的应用 基本函数: void T0(void) interrupt 1 using 1 { 这里放入中断后需要做的操作 } void T0(void)&#xff1a; 这是一个函数声明&#xff0c;表明函数 T0 不接受任何参数&#xff0c;并且不返回任何值。 interrupt 1&#xff1a; 这是关键字和参…

ffmpeg安装(windows)

ffmpeg安装-windows 前言ffmpeg安装路径安装说明 前言 ffmpeg的安装也是开箱即用的,并没有小码哥说的那么难 ffmpeg安装路径 这就下载好了! 安装说明 将上面的bin目录加入到环境变量,然后在cmd中测试一下: C:\Users\12114\Desktop\test\TaskmgrPlayer\x64\Debug>ffmpe…

HCIA笔记6--路由基础

0. 概念 自治系统&#xff1a;一个统一管理的大型网络&#xff0c;由路由器组成的集合。 路由器隔离广播域&#xff0c;交换机隔离冲突域。 1.路由器工作原理 路由器根据路由表进行转发数据包&#xff1b; 路由表中没有路由&#xff0c;直接丢弃该数据包路由表中只有一条路…

IDEA如何快速地重写方法,如equals、toString等

前言 大家好&#xff0c;我是小徐啊。我们在使用IDEA的时候&#xff0c;有时候是需要重写equals和toString等方法的。这在IDEA中已经很方便的给我们准备好了快速的操作了。今天就来讲解一下。 如何重写 首先&#xff0c;打开要重写方法的文件&#xff0c;让鼠标定位到这个文…