【算法】堆与优先级队列

【ps】本篇有 4 道 leetcode OJ。

目录

一、算法简介

二、相关例题

1)最后一块石头的重量

.1- 题目解析

.2- 代码编写

2)数据流中的第 K 大元素

.1- 题目解析

.2- 代码编写

3)前K个高频单词

.1- 题目解析

.2- 代码编写

4)数据流的中位数

.1- 题目解析

.2- 代码编写


 

一、算法简介

        普通队列的特点是先进先出,元素在队尾入队,而从队首出队。优先级队列则不同,队列中的每个元素都被赋予了一个权值,权值较高的元素排在最前优先出队。它一般默认通过一个大根堆(即权值以从高到低排列)实现,表现为一个以 vector 为底层的完全二叉树。

        优先级队列常与模拟算法一起出题。除了要掌握如何对优先级队列建大根堆或小根堆,还要能够不借助 STL 提供的优先级队列来自己实现堆这种数据结构,因为这是面试场上常考的(欲知堆的更多细节,请见【数据结构】树之二叉树)。

二、相关例题

1)最后一块石头的重量

1046. 最后一块石头的重量

.1- 题目解析

        对于从一个序列中选出最大值,不难想到堆排序和优先级队列。我们可以将数组中的元素全部插入优先级队列中,然后依此从堆顶取两个元素进行“粉碎”,这两个元素其中一个一定是当前数组中最大的,另一个一定是次大的。如果它们两个相等,就不作处理,相当于两个都“粉碎”了;如果不相等,就将它们的差值入队......以此类推,直至优先级队列中没有元素或仅剩一个元素。

.2- 代码编写

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

2)数据流中的第 K 大元素

703. 数据流中的第 K 大元素

.1- 题目解析

        这是一道典型的 Top-K 问题,其解决方法有堆排序、基于快排的快速选择算法。尽管快速选择算法的时间复杂度为 O(n),堆排序为 O(n*logK),但面对海量数据时,快速选择算法的空间复杂度颇高,因此此处选用更优的堆排序来解题。

        具体方式是,创建一个大小为 k 的堆,如果是找第 k 大(排降序)就创建小根堆,找第 k 小(排升序)就创建大根堆。然后将待排序的元素依此进堆,每次进堆都判断一下堆的大小是否超过 k,如此,堆顶存放的就一直是第 k 大或第 k 小的元素。

.2- 代码编写

class KthLargest {priority_queue<int,vector<int>,greater<int>> heap;//排降序建小根堆int _k;
public://显示的构造函数KthLargest(int k, vector<int>& nums) {_k=k;for(auto x:nums){//先将元素入堆进行排序heap.push(x);//堆的大小超过k,就把堆顶元素取出,只留下第k大的元素在堆顶if(heap.size()>_k)heap.pop();}}int add(int val) {heap.push(val);if(heap.size()>_k)heap.pop();return heap.top();}
};/*** Your KthLargest object will be instantiated and called as such:* KthLargest* obj = new KthLargest(k, nums);* int param_1 = obj->add(val);*/

3)前K个高频单词

692. 前K个高频单词

.1- 题目解析

        这也是一道典型的 Top-K 问题。在进行堆排序找到前 k 个高频单词之前,我们需要先对数组中的单词出现的频次进行统计,这样才能进行堆排序。

        而特别的,一般情况下应按单词出现频率由高到低排序,此时应建小堆;当不同的单词有相同频次时, 就要按字典序来排序,此时应建大堆。那么,我们就需要对建堆的排序函数进行特殊处理。

        由于堆顶存放的是频次前 k 大中频次最小的单词,因此从堆顶依此取元素并插入到数组中的时候,需要将元素从后往前插入到数组中,或者从前往后插入,最终将数组逆序。

.2- 代码编写

class Solution {typedef pair<string,int> PSI;struct cmp{bool operator()(const PSI& a,const PSI& b){if(a.second==b.second)return a.first<b.first;return a.second>b.second;}};
public:vector<string> topKFrequent(vector<string>& words, int k) {//1.用哈希表统计频次unordered_map<string,int> hash;for(auto&s:words)hash[s]++;//2.建堆priority_queue<PSI,vector<PSI>,cmp> heap;for(auto& x:hash){heap.push(x);if(heap.size()>k)heap.pop();}//3.统计结果vector<string> ret(k);for(int i=k-1;i>=0;i--){ret[i]=heap.top().first;heap.pop();}return ret;}
};

4)数据流的中位数

295. 数据流的中位数

.1- 题目解析

        要找到一个中位数,这个数据序列必须是有序的。我们可以将一个排好序的序列一分为二,将序列左边的所有元素放入大根堆里,将序列右边的所有元素放入小根堆里,如此,大根堆的堆顶就是序列左边的最大元素,小根堆的堆顶就说序列右边的最小元素,此时只要把这两个堆顶元素相加除以 2,就能得到整个序列的中位数了。

        设 num 是一个待插入堆的元素,m 为序列左边的元素个数,n 为序列右边的元素个数,则:

.2- 代码编写

class MedianFinder {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);int rightTop=right.top();right.pop();left.push(rightTop);}}else if(left.size()==right.size()+1){if(num<=left.top()){left.push(num);int leftTop=left.top();left.pop();right.push(leftTop);}else {right.push(num);}}}double findMedian() {if(left.size()==right.size())return (left.top()+right.top())/2.0;else return left.top();}
};/*** Your MedianFinder object will be instantiated and called as such:* MedianFinder* obj = new MedianFinder();* obj->addNum(num);* double param_2 = obj->findMedian();*/

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

d2l | 目标检测数据集:RuntimeError: No such operator image::read_file

目录 1 存在的问题2 可能的解决方案3 最终的解决方案3.1 方案一&#xff08;我已弃用&#xff09;3.2 方案二&#xff08;基于方案一&#xff09; 1 存在的问题 李沐老师提供的读取香蕉数据集的函数如下&#xff1a; def read_data_bananas(is_trainTrue):""…

yolov10算法原理

文章目录 1. 模型效果2. 模型特点2.1 无NMS训练的一致性双重分配策略 (Consistent Dual Assignments for NMS-free Training)双重标签分配 (Dual Label Assignments)一致匹配度量&#xff08;Consistent Match. Metric&#xff09;一对一分配在一对多结果中的频率 2.2. 效率-准…

C++基础:第一个C++程序

初学C #include<iostream> int main() {std::cout << "Enter two numbers:" << std::endl;int v1 0, v2 0;std::cin >> v1 >> v2;std::cout << "The sum of "<< v1 << " and " << v2&…

Ubuntu磁盘不足扩容

1.问题 Ubuntu磁盘不足扩容 2.解决方法 安装一下 sudo apt-get install gpartedsudo gparted

JavaWeb--小白笔记07:servlet对表单数据的简单处理

这里的servlet对表单数据的处理是指使用IDEA创建web工程&#xff0c;再创建html和class文件进行连接&#xff0c;实现html创建一个表单网页&#xff0c;我们对网页中的表单进行填充&#xff0c;可以通过class文件得到网页我们填充的内容进行打印到控制台。 一登录系统页面---h…

【速成Redis】04 Redis 概念扫盲:事务、持久化、主从复制、哨兵模式

前言&#xff1a; 前三篇如下&#xff1a; 【速成Redis】01 Redis简介及windows上如何安装redis-CSDN博客 【速成Redis】02 Redis 五大基本数据类型常用命令-CSDN博客 【速成Redis】03 Redis 五大高级数据结构介绍及其常用命令 | 消息队列、地理空间、HyperLogLog、BitMap、…

自然语言处理-基于注意力机制的文本匹配

背景&#xff1a; 任务三&#xff1a;基于注意力机制的文本匹配 输入两个句子判断&#xff0c;判断它们之间的关系。参考ESIM&#xff08;可以只用LSTM&#xff0c;忽略Tree-LSTM&#xff09;&#xff0c;用双向的注意力机制实现。 参考 《神经网络与深度学习》 第7章 Reaso…

rar文件怎么打开?这几款软件压缩和查看很方便!

在这个数字化信息爆炸的时代&#xff0c;我们每天都会接触到各种各样的文件&#xff0c;其中RAR格式文件以其高压缩率和良好的文件保护特性&#xff0c;成为了许多人分享和存储大文件的首选。然而&#xff0c;面对这样一个看似“神秘”的文件格式&#xff0c;不少朋友可能会感到…

如何基于Flink CDC与OceanBase构建实时数仓,实现简化链路,高效排查

本文作者&#xff1a;阿里云Flink SQL负责人&#xff0c;伍翀&#xff0c;Apache Flink PMC Member & Committer 众多数据领域的专业人士都很熟悉Apache Flink&#xff0c;它作为流式计算引擎&#xff0c;流批一体&#xff0c;其核心在于其强大的分布式流数据处理能力&…

简单多状态dp第一弹 leetcode -面试题17.16.按摩师 -213.打家劫舍II

a​​​​​​​面试题 17.16. 按摩师 按摩师 题目: 分析: 使用动态规划解决 状态表示: dp[i] 表示&#xff1a;选择到 i 位置时&#xff0c;此时的最长预约时长。 但是我们这个题在 i 位置的时候&#xff0c;会面临 选择 或者 不选择 两种抉择&#xff0c;所依赖的状态需要…

大数据Flink(一百二十四):案例实践——淘宝母婴数据加速查询

文章目录 案例实践——淘宝母婴数据加速查询 一、​​​​​​​创建数据库表并导入数据 二、​​​​​​​​​​​​​​创建session集群 三、​​​​​​​​​​​​​​源表查询 四、​​​​​​​​​​​​​​指标计算 案例实践——淘宝母婴数据加速查询 随着…

GS-SLAM论文阅读笔记--GLC-SLAM

前言 最近GS-SLAM回环检测的工作已经逐步发展了&#xff0c;看一下这篇新文章。 文章目录 前言1.背景介绍2.关键内容2.1 tracking2.2 local mapping2.3 Loop Closing2.4总体流程 3.文章贡献 1.背景介绍 现有的基于3dgs的SLAM方法往往存在累积的跟踪误差和地图漂移&#xff0c…

【后端开发】JavaEE初阶—线程安全问题与加锁原理(超详解)

前言&#xff1a; &#x1f308;上期博客&#xff1a;【后端开发】JavaEE初阶—Theard类及常见方法—线程的操作&#xff08;超详解&#xff09;-CSDN博客 &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f308;小编会在后端开发的学习中不…

Java反射机制入门:解锁运行时类信息的秘密

反射技术&#xff1a; 其实就是对类进行解剖的技术 类中有什么&#xff1f;构造方法 成员方法成员变量 结论&#xff1a;反射技术就是把一个类进行了解剖&#xff0c;然后获取到 构造方法、成员变量、成员方法 反射技术的应用案例&#xff1a; idea框架技术&#xff1a;Spr…

通过document获取节点元素

1.层级节点 <ul><li id"li1">1</li><li>2</li><li id"li3">3</li><li>4</li><li>5</li></ul><script>//获取id名为li1的元素赋值给li1let li1document.getElementById(li…

爬虫----webpack

目录 一. 什么是webpack 出现的原因&#xff1a;同名函数 概念: 特征&#xff1a;大量缩进 webpack的格式 简单的webpack格式&#xff1a; 详细的webpack格式&#xff1a; 几个参数的运用 1. webpack数组形式 2. webpack对象格式 3.多个js文件打包 打印要扣的代码 …

【chromedriver编译-绕过selenium机器人检测】

有小伙伴说使用selenium没能绕过机器人检测&#xff0c;盘他。 selenium机器人检测有2种&#xff0c;一是cdp检测&#xff0c;二是webdriver特征检测。cdp检测前面的博客已写过&#xff0c;这里就提下webdriver特征检测。一、selenium简介 Selenium 是一个强大的工具&#xff…

单片机带隙电压基准电路

单片机带隙电压基准电路 一、带隙电压基准电路概述 带隙电压基准电路在单片机中占据着至关重要的地位。它能够为各种模拟集成电路提供稳定的参考电压&#xff0c;确保电路的正常运行。例如&#xff0c;在高精度的比较器中&#xff0c;带隙电压基准电路可以提供一个精确的参考…

linux 的 sed 命令的 使用学习

&#xff08;1&#xff09; sed 概述&#xff1a; &#xff08;2&#xff09; 首先谢谢 b 站这位老师&#xff0c;这位专家的完美讲解 讲解继续&#xff1a; &#xff08;3&#xff09; 关于 sed 里的模式&#xff1a; &#xff08;4&#xff09; sed 支持的常用的对文本编辑的…

Matlab|考虑柔性负荷的综合能源系统低碳经济优化调度

目录 1 主要内容 2 部分代码 3 程序结果 4 下载链接 1 主要内容 程序主要实现的是考虑柔性负荷的综合能源系统低碳经济优化调度&#xff0c;模型参考《考虑柔性负荷的综合能源系统低碳经济优化调度》&#xff0c;求解方法采用的是混合整数规划算法&#xff0c;通过matlabc…