LeetCode 热题 100 | 堆(二)

目录

1  什么是优先队列

1.1  优先队列与堆的关系

1.2  如何定义优先队列

1.3  如何使用优先队列

1.4  如何设置排序规则

2  347. 前 K 个高频元素

2.1  第 2 步的具体实现

2.2  举例说明

2.3  完整代码

3  215. 数组中的第 K 个最大元素 - v2


菜鸟做题,语言是 C++

1  什么是优先队列

1.1  优先队列与堆的关系

优先队列:它是一种抽象数据类型,可以看作是一个队列或栈的变体,元素按照优先级的高低排列。在 C++ 中,优先队列通常使用堆来实现。

个人理解,优先队列是对堆的底层原理的封装,谁不用谁是傻子 (bushi)

1.2  如何定义优先队列

参考博客:c++ 优先队列(priority_queue)用法详解

定义如下:

priority_queue<Type, Container, Functional>

① Type 是指数据类型,即你要装什么类型的数据。

② Container 是指容器类型,即你用什么样的容器装数据。

Container 必须是用数组实现的容器,比如:vector、deque等等,不能用 list 。STL 里面默认用的是 vector 。

③ Functional 是指比较的方式,即你希望数据之间以什么样的规则来排序。

只有当数据类型比较复杂的时候才需要设置 Functional,比如你的数据是个键值对。针对基本的数据类型,不需要设置 Functional,默认是大根堆(即谁大谁排前面)。

举例说明

假设我要让优先队列装 int 型的数据,那么就有:

priority_queue<int, vector<int>> q;

如果我不想使用默认的大根堆排序方法,则有:

priority_queue<int, vector<int>, decltype(& cmp)> q(cmp);

其中 cmp 是你自定义的排序函数,返回值是 bool 类型。

如果我想让优先队列装键值对类型的数据,则有:

priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(& cmp)> q(cmp);

不过就是把数据类型换了,基本结构都是一样的。

1.3  如何使用优先队列
  • q.push(data) 插入元素
  • q.pop() 弹出队首元素
  • q.top() 获取队首元素
  • q.size() 获取队列大小
  • q.empty() 判断是否为空

以上就是优先队列的基本操作,可以看出它和栈、队列的操作是一样的,无痛学习。

1.4  如何设置排序规则

假设我要为键值对排序,因此对队列定义如下:

priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(& cmp)> q(cmp);

其中,pair<int, int> 的第一个 int 是键,第二个 int 是值。要求 cmp 是一个函数指针(即函数的地址),decltype 是类型推导。

排序规则如下:

static bool cmp(pair<int, int> m, pair<int, int> n) {return m.second > n.second;
}

其中,m.second 和 n.second 分别代表键值对 m 和 n 的值。

Q:为什么要加 static?

A:因为不加会报错:

  • “error: must explicitly qualify name of member function when taking its address”
  • “错误:在取成员函数的地址时必须显式限定成员函数的名称”

为什么是 m.second > n.second?这样看起来不是谁的值更大,谁排前面吗?答:我也不知道啊。

2  347. 前 K 个高频元素

好不容易通过  215. 数组中的第 K 个最大元素  学会了堆排序,准备大展身手,结果运行超时。。

解题思路:

  1. 遍历 nums 并使用 hash 为其中的所有数字计数
  2. 遍历 hash 并使用 priority_queue 为其中的计数结果排序

2.1  第 2 步的具体实现

① 定义优先队列:

priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(& cmp)> q(cmp);

为什么存储的数据类型是 pair<int, int>?因为我们要同时存储 “数字” 和它的 “个数”,否则后面把 “个数” 的顺序排出来了,却不知道这些 “个数” 对应的 “数字” 是哪些。

② 遍历 hash 并使用 priority_queue 为其中的计数结果排序:

  • 依次向 priority_queue 插入数据,但限制 priority_queue 的大小最终为 k
  • 若当前元素的 count 比队首元素的 count 大,那么弹出队首,换当前元素进去
for (auto & [num, count] : hash) {if (q.size() < k) {q.push(make_pair(num, count));} else if (q.size() == k) {if (count > q.top().second) {q.pop();q.push(make_pair(num, count));}}
}

2.2  举例说明

这里用字母只是为了方便区分,原题还是用的数字

  • 假设 nums = [a, b, b, c, c, c], k = 2
  • 易得 hash = [(a, 1), (b, 2), (c, 3)]

下面来看 priority_queue 是怎么操作的:

第 1 时刻,队列大小显然没有到达 k,因此直接插入键值对。第 2 时刻,队列大小显然也没有到达 k,因此直接插入键值对。第 3 时刻,由于席位已满,因此必须判断谁更配进入队列。由于 a 的个数被 c 的个数少,因此 a 被弹出队列为 c 让位。

注意:每当有新元素进入队列的时候,队列都会按照之前设置的排序规则 cmp 为元素重新排队。

2.3  完整代码
class Solution {
public:// 排序规则static bool cmp(pair<int, int> m, pair<int, int> n) {return m.second > n.second;}vector<int> topKFrequent(vector<int>& nums, int k) {// 计数unordered_map<int, int> hash;for (auto & n : nums) {hash[n]++;}// 排序priority_queue<pair<int, int>, vector<pair<int, int>>,decltype(& cmp)> q(cmp);for (auto & [num, count] : hash) {if (q.size() < k) {q.push(make_pair(num, count));} else if (q.size() == k) {if (count > q.top().second) {q.pop();q.push(make_pair(num, count));}}}// 处理结果vector<int> ans;while (!q.empty()) {ans.push_back(q.top().first);q.pop();}return ans;}
};

3  215. 数组中的第 K 个最大元素 - v2

模仿  347. 前 K 个高频元素  即可

class Solution {
public:static bool cmp(int a, int b) {return a > b;}int findKthLargest(vector<int>& nums, int k) {priority_queue<int, vector<int>, decltype(& cmp)> q(cmp);for (auto & n : nums) {if (q.size() < k) {q.push(n);} else if (q.size() == k) {if (n > q.top()) {q.pop();q.push(n);}}}return q.top();}
};


当你有了优先队列,谁还看堆排 (〃>皿<)

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

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

相关文章

Shell学习

一、 变量 shell是弱类型语言&#xff0c;不用定义数据类型&#xff0c;默认都是字符串。 变量与值之间不得有空格 只能包含数字、字母、下划线 不能以数字开头 区分大小写 根据变量的作用域可以将shell变量分为&#xff1a;全局变量、局部变量、环境变量。全局变量通常和…

app自动化测试怎么学?

app测试的主要内容有那些 1、功能测试 : 查看功能是否正常&#xff0c;主要针对每一个功能点进行一一测试&#xff0c;主要核心就是把验证的每个测试点都满足需求的对应功能&#xff0c;验证标准就是让预期结果和实际结果保持一致。 2、安装卸载测试&#xff1a;首先要测试的…

【Linux】从零认识进程 — 中下篇

送给大家一句话&#xff1a; 人一切的痛苦&#xff0c;本质上都是对自己无能的愤怒。而自律&#xff0c;恰恰是解决人生痛苦的根本途径。—— 王小波 从零认识进程 1 进程优先级1.1 什么是优先级1.2 为什么要有优先级1.3 Linux优先级的特点 && 查看方式1.4 其他概念 2…

深度解析深度学习中的长短期记忆网络(LSTM)(含代码实现)

在深度学习中&#xff0c;长短期记忆网络&#xff08;LSTM&#xff09;是一种强大的循环神经网络结构&#xff0c;能够更好地处理长序列数据并减轻梯度消失的问题。本文将介绍LSTM的工作原理&#xff0c;并使用PyTorch实现一个简单的LSTM模型来展示其在自然语言处理中的应用。 …

MongoDB完全开发手册(一篇学会MongoDB所有知识点)

目录 一、MongoDB 基础 1.1 、MongoDB 是什么&#xff1f; 1.2、 MongoDB 的存储结构是什么&#xff1f; 1.3 、文档 1.4 、集合 1.5 、数据库 1.6、 MongoDB 有什么特点&#xff1f; 1.7、 MongoDB 适合什么应用场景&#xff1f; 二、MongoDB 存储引擎 2.1 、MongoDB…

Autosar Crypto Interface学习笔记

文章目录 前言Functional specificationError classificationError detection API specificationType DefinitionsFunction definitionsGeneral APICryIf_InitCryIf_GetVersionInfo Job Processing InterfaceCryIf_ProcessJobDispatch Key IDs匹配KeyId Job Cancellation Inter…

【嵌入式——QT】Charts常见的图表的绘制

【嵌入式——QT】Charts常见的图表的绘制 柱状图QBarSetQBarSeriesQBarCategoryAxis图示 饼图堆叠柱状图百分比柱状图散点图和光滑曲线图代码示例 柱状图 QBarSet 用于创建柱状图的数据集。 主要函数 setLabel()&#xff1a;设置数据集标签 &#xff1b;setLabelBrush()&am…

租用阿里云2核2G服务器配置报价,61元和99元

阿里云2核2G服务器配置优惠价格61元和99元&#xff0c;61元是轻量应用服务器2核2G3M带宽、50G高效云盘&#xff0c;99元服务器是ECS云服务器经济型e实例2核2G、3M固定带宽、40G ESSD entry 系统盘。活动 aliyunfuwuqi.com/go/aliyun 阿里云服务器网aliyunfuwuqi.com根据上面的官…

​ YOLOv9改进策略:SPPELAN优化 | 新一代高效可形变卷积DCNv4如何做二次创新?高效结合SPPELAN| CVPR2024

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文改进内容&#xff1a; DCNv4来自CVPR2024 的论文&#xff0c;它不仅收敛速度明显快于DCNv3&#xff0c;而且正向速度提高了3倍以上。这一改进使DCNv4能够充分利用其稀疏特性&#xff0c;成为最快的通用核心视觉算子之一。 |新一代…

如何减少pdf的文件大小?pdf压缩工具介绍

文件发不出去&#xff0c;有时就会耽误工作进度&#xff0c;文件太大无法发送&#xff0c;这应该是大家在发送PDF时&#xff0c;常常会碰到的问题吧&#xff0c;那么PDF文档压缩大小怎么做呢&#xff1f;因此我们需要对pdf压缩后再发送&#xff0c;那么有没有好用的pdf压缩工具…

牛客题霸-SQL进阶篇(刷题记录二)

本文基于前段时间学习总结的 MySQL 相关的查询语法&#xff0c;在牛客网找了相应的 MySQL 题目进行练习&#xff0c;以便加强对于 MySQL 查询语法的理解和应用。 由于涉及到的数据库表较多&#xff0c;因此本文不再展示&#xff0c;只提供 MySQL 代码与示例输出。 部分题目因…

烯冷新能源邀您参观2024长三角快递物流展

参加企业介绍 宁波戈雷贝拓科技有限公司&#xff08;宁波烯冷新能源科技有限公司&#xff09;宁波烯冷新能源科技有限公司于2022年初成立&#xff0c;依托中国科学院宁波材料技术与工程研究所和国家石墨烯创新中心&#xff0c;公司开发产品包括&#xff1a;新能源制冷系统和集…

深入理解Netty以及为什么项目中要使用?(六)Netty核心组件实例

调度器详解 前面我们讲过NIO多路复用的设计模式之Reactor模型&#xff0c;Reactor模型的主要思想就是把网络连接、事件分发、任务处理的职责进行分离&#xff0c;并且通过引入多线程来提高Reactor模型中的吞吐量。其中包括三种Reactor模型 单线程单Reactor模型 多线程单React…

【Python + Django】表结构创建

以员工管理系统为例。 事前呢&#xff0c;我们先把项目和app创建出来&#xff0c;详细步骤可以看我同栏目的第一篇、第二篇文章。 我知道你们是不会下来找的&#xff0c;就把链接贴在下面吧&#xff1a; 【Python Django】启动简单的文本页面-CSDN博客 【Python Django】…

Microsoft Windows 10 22H2官方简体中文正式版2023年12月更新版(最新微软原版ISO镜像)

Microsoft Windows 10 22H2官方简体中文正式版2023年12月更新版(最新微软原版ISO镜像) 将标红的地址放大迅雷里面下载就好&#xff01; MVS Microsoft Windows 10 22H2 官方正式版2023年12月版ISO镜像微软订阅中心发布信息 简体中文商业版2023年12月版&#xff08;教育版、…

【C语言进阶篇】动态内存管理

【C语言进阶篇】动态内存管理 &#x1f308;个人主页&#xff1a;开敲 &#x1f525;所属专栏&#xff1a;C语言 &#x1f33c;文章目录&#x1f33c; 1. 为什么要有动态内存分配 2.动态内存开辟和释放函数 2.1 动态内存释放函数 2.1.1 free函数 2.2 动态内存开辟函数 2.2.1 …

【鸿蒙HarmonyOS开发笔记】应用数据持久化之通过用户首选项实现数据持久化

概述 应用数据持久化&#xff0c;是指应用将内存中的数据通过文件或数据库的形式保存到设备上。内存中的数据形态通常是任意的数据结构或数据对象&#xff0c;存储介质上的数据形态可能是文本、数据库、二进制文件等。 HarmonyOS标准系统支持典型的存储数据形态&#xff0c;包…

OceanPen Art AI绘画系统 运营教程(三)2.10绘画全新界面升级

在一个崇高的目标支持下&#xff0c;不停地工作&#xff0c;即使慢&#xff0c;也一定会获得成功。 —— 爱因斯坦 演示站点&#xff1a; ai.oceanpen.art 官方论坛&#xff1a; www.jingyuai.com 一、前端用户界面全新体验 二、 MJ绘画分享 提示词自取&#xff1a;htt…

如何使用 ArcGIS Pro 制作好看的高程渲染图

虽然 ArcGIS Pro 已经提供了很多好看的配色方案&#xff0c;但是如果直接对高程DEM进行渲染效果不是很理想&#xff0c;我们可以结合山体阴影让高程渲染图看起来更加立体&#xff0c;这里为大家介绍一下制作方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是…

component-右侧抽屉组件

1.右侧抽屉组件 点击筛选&#xff0c;右侧抽屉滑出&#xff0c;点击取消或者点击空白处抽屉收起。 2.代码 <template><div class"all" click"hidden()"><!-- 抽屉 --><div class"drawer"><div class"drawerBo…