【leetcode】优先级队列的两种妙用:词频统计与动态中位数(附代码模板)

article/2025/8/14 20:59:39

前言

🌟🌟本期讲解关于力扣的几篇题解的详细介绍~~~

🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客

🔥 你的点赞就是小编不断更新的最大动力                                       

🎆那么废话不多说直接开整吧~~

目录

📚️1.前K个高频单词

🚀1.1题目描述

🚀1.2题目解析

🚀1.3代码编写

📚️2.数据流的中位数

🚀2.1题目描述

🚀2.2题目解析

2.2.1第一种思路

2.2.2第二种思路

🚀2.3代码编写

2.3.1第一种代码

2.3.2第二种代码

📚️3.总结

——前言:关于堆这个数据结构,想必大家多多少少已经了解,并熟悉过了;其中最经典的问题就是使用堆来解决TOPK问题,但是除次之外,堆的构建以及堆来求解中位数,那么不知道大家了解过没有~~~ 

📚️1.前K个高频单词

🚀1.1题目描述

给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。

返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序。

第一种情况:

输入: words = ["i", "love", "leetcode", "i", "love", "coding"], k = 2

输出: ["i", "love"] 解析: "i" 和 "love" 为出现次数最多的两个单词,均为2次。

注意,按字母顺序 "i" 在 "love" 之前。

 第二种情况:

输入: ["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], k = 4

输出: ["the", "is", "sunny", "day"]

解析: "the", "is", "sunny" 和 "day" 是出现次数最多的四个单词,出现次数依次为 4, 3, 2 和 1 次

具体解析过后就是:求出现次数最多的单词,如果次数一样,就按照字典顺序进行排序操作~~

🚀1.2题目解析

看到前k个这个关键字,咱们想到的就是堆排。统计单词出现的个数,那么很明显就是使用哈希表来实现我们的单词和次数的存储,即一个字符串类型记录单词,一个整数类型记录出现的次数;

但是~~,本题最关键的问题就是,在满足两者次数相同的时候,这个按照字典序列进行排序,这个就是一个关键

思路:

第一种情况:按照次数进行入堆的操作,那么我们要找次数大的那么就直接创建一个小根堆

第二种情况:遇到次数相同的,那么字典序小的在前面,那么创建一个大根堆

即找前几小的,创建大根堆;找前几大的,创建小根堆;

 那么这里关键就是如何创建我们的堆了;

所以总结:

1.将我们的字符串数组遍历,将对应的字符串和次数存入哈希表中

2.依据条件创建我们的堆

3.遍历我们的哈希表存入我们的堆中

4.获取结果

🚀1.3代码编写

代码如下:

class Solution {public List<String> topKFrequent(String[] words, int k) {Map<String,Integer> map = new HashMap<>();//遍历我们的字符数组进行添加for(String s : words){map.put(s, map.getOrDefault(s,0) + 1);}//创建我们的大小根堆PriorityQueue<Pair<String,Integer>> heap = new PriorityQueue<>((a,b) ->{if(a.getValue().equals(b.getValue())){//如果次数相同,那么根据字典序比较大根堆return b.getKey().compareTo(a.getKey());}return a.getValue() - b.getValue();});//遍历我们的哈希表,并存入我们的优先级队列中for(Map.Entry<String,Integer> e : map.entrySet()){heap.offer(new Pair<String,Integer>(e.getKey(),e.getValue()));if(heap.size() > k){heap.poll();}}List<String> ret = new ArrayList<>();//拿到数据while(!heap.isEmpty()){ret.add(heap.poll().getKey());}Collections.reverse(ret);return ret;}
}

解释:

第一:在保存我们的字符串以及次数在哈希表中时,注意为0时的情况;

第二:在根据条件,通过lambda表达式创建我们的堆

第三:遍历哈希表中,存入堆中,要判断堆的长度

第四:保存我们的数据后,要记得翻转我们的列表

📚️2.数据流的中位数

🚀2.1题目描述

中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。

  • 例如 arr = [2,3,4] 的中位数是 3 。
  • 例如 arr = [2,3] 的中位数是 (2 + 3) / 2 = 2.5 。

实现 MedianFinder 类:

  • MedianFinder() 初始化 MedianFinder 对象。

  • void addNum(int num) 将数据流中的整数 num 添加到数据结构中。

  • double findMedian() 返回到目前为止所有元素的中位数。与实际答案相差 10-5 以内的答案将被接受。

 当然其实就是三个函数:第一初始化我们的数据结构,第二添加我们的值到我们的数据结构中,第三返回我们数据结构中的中位数;

当然中位数就是:在一堆有序数中的中间值,若时偶数倍,那么就是中间两个值之和除以2;奇数倍即有序数中的中间那个值;(这个大家初中小学就应该学过了吧 ^ _ ^)

🚀2.2题目解析

2.2.1第一种思路

其实第一种思路其实非常简单,就是我们在每次加入数据后,对整个数组进行排序,然后在我们的找中间值的时候,我们根据我们数组的长度来进行判断(分为奇数,与偶数),然后获取我们的中位数;

如下图:

这里小编就不再过多解释了(肯定超时了)~~~

2.2.2第二种思路

第二种思路就是使用我们的堆来进行操作,是不是很意外;

我们思路就是:将整个有序数组分为两变;左边创建一个大根堆,右边创建一个小根堆;并且我们的两个堆的长度左边堆长度:m;右边堆长度:n

满足条件:m == n + 1或者m == n;

主要是为了在奇数长度下直接取左边大根堆对顶,偶数条件下取两个堆对顶然后除以2即可;

为啥呢?

1.我们的思路是在两个堆对顶进行中位值的获取,若不满足上述条件就会导致操作堆顶不能满足中位数获取~~~

2.我们拿到一个数该放入右边还是左边呢?这里我们统一按照大根堆对顶进行参照

3.假如m == n+1;但是要放入我们的m,那么此时咋办:

    直接插入我们的大根堆,然后大根堆出堆放入我们小根堆,就可以完成堆的维护了

    同理 m == n,如果要插入我们的小根堆,那么我们将小根堆的堆顶元素放入我们的大根        堆就可以了;

假如我们m == n + 1,但是此时哦们要插入大根堆,那么就要维护我们的两个堆,如下所示:

总结就是:

中间值,要靠两个堆对顶来进行获取;

不断在添加数值后,依据我们的m == n + 1或者m == n来进行堆的维护 

🚀2.3代码编写

2.3.1第一种代码

如下所示:

class MedianFinder {List<Integer> ret ;public MedianFinder() {ret = new ArrayList<>();}public void addNum(int num) {ret.add(num);//进行排序Collections.sort(ret);}public double findMedian() {double temp;//进行取值判断if(ret.size() %2 == 0){int index = ret.size()/2;temp = (double)(ret.get(index) + ret.get(index-1))/2;}else{int index = ret.size()/2;temp = (double)(ret.get(index));}return temp;}
}

这里的排序是通过sort进行排序的哈~~~

2.3.2第二种代码

如下所示:

class MedianFinder {//创建一个大根堆,小根堆PriorityQueue<Integer> maxHeap;PriorityQueue<Integer> minHeap;public MedianFinder() {maxHeap = new PriorityQueue<>((a,b) -> b-a);minHeap = new PriorityQueue<>(); }public void addNum(int num) {//维护我们的大小堆int m = maxHeap.size();int n = minHeap.size();if(m == n){//进入左边if(m == 0 || num <= maxHeap.peek()){maxHeap.offer(num);}else{minHeap.offer(num);int temp = minHeap.poll();maxHeap.offer(temp);}}else if(m == n + 1){if(num <= maxHeap.peek()){maxHeap.offer(num);int temp = maxHeap.poll();minHeap.offer(temp);}else{minHeap.offer(num);}}}public double findMedian() {double median;if(maxHeap.size() == minHeap.size()){median = (double)(maxHeap.peek() + minHeap.peek())/2;}else{median =(double) maxHeap.peek();}return median;}
}

解释:

其实就是根据两个堆的长度是否满足我们上述分析的两种条件;我们每次插入数据时,都要peek一下我们大根堆的堆顶元素,插入后要判断是否会打断我们m == n || m == n + 1的条件,如若打乱了我们的条件,那么就要进行维护(将一个堆的堆顶,放入另一个堆即可)

最后在查找我们的中间值的时候,根据我们两个堆的长度进行判断我们应该取大根堆堆顶还是两个堆堆顶的和再除以2;

📚️3.总结

本期小编主要是针对力扣上两道关于堆的题目进行讲解:前K个高频单词,数据流的中位数;

692. 前K个高频单词 - 力扣(LeetCode)​​​​​​

295. 数据流的中位数 - 力扣(LeetCode)

🌅🌅🌅~~~~最后希望与诸君共勉,共同进步!!!


💪💪💪以上就是本期内容了, 感兴趣的话,就关注小编吧。

😊😊  期待你的关注~~~


http://www.hkcw.cn/article/VwLkXHTNWN.shtml

相关文章

【算法学习】哈希表篇:哈希表的使用场景和使用方法

算法学习&#xff1a; https://blog.csdn.net/2301_80220607/category_12922080.html?spm1001.2014.3001.5482 前言&#xff1a; 在之前学习数据结构时我们就学习了哈希表的使用方法&#xff0c;这里我们主要是针对哈希表的做题方法进行讲解&#xff0c;都是leetcode上的经典…

HDFS详解

一、HDFS 概述 定位与特点 分布式文件系统&#xff1a;HDFS&#xff08;Hadoop Distributed File System&#xff09;是 Hadoop 生态的核心组件&#xff0c;专为海量数据存储和批处理设计。 核心设计原则&#xff1a; 高容错性&#xff1a;数据自动多副本冗余&#xff0c;支持…

【数据结构】String字符串的存储

目录 一、存储结构 1.字符串常量池 2.字符串哈希表 2.1结构 2.2基础存储单位 2.2.1键对象 2.2.2值对象 二、存储过程 1.搜索 2.创建 三、存储位置 四、存储操作 1.new新建 2.intern入池 这是String类的详解&#xff1a;String类变量 一、存储结构 1.字符串常量池…

数据结构大作业——家谱管理系统(超详细!完整代码!)

目录 设计思路&#xff1a; 一、项目背景 二、功能分析 查询功能流程图&#xff1a; 管理功能流程图&#xff1a; 三、设计 四、实现 代码实现&#xff1a; 头文件 结构体 函数声明及定义 创建家谱树头结点 绘制家谱树&#xff08;打印&#xff09; 建立右兄弟…

北京将有7级大风小冰雹 雷电蓝色预警发布

6月1日17时50分,北京发布雷电蓝色预警,预计当天20时至次日2时,自西向东将有雷阵雨天气,局地短时雨强较大,并伴有7级左右短时大风和小冰雹,请注意防范。明天上午至中午前后依旧会出现分散性雷阵雨,雨量总体不大。午后至前半夜北风增强,阵风明显,外出时请做好防风措施,…

专家:印太战略实质是霸权工具 不会得逞

针对美国防长赫格塞思在香格里拉对话会上涉及中国的部分表态,有中国学者指出,美国所谓的“印太战略”实质上是霸权工具,不会得逞。在对话会上,赫格塞思再次提到所谓的“印太战略”,并呼吁亚太地区同盟国和合作伙伴国与美国一起构筑更现实的战略关系。国防大学教授孟祥青表…

SCNN(Spatial CNN) 模型学习记录

目录 1.模型架构 2.核心模块SCNN_*分析 SCNN&#xff08;Spatial As Deep: Spatial CNN for Traffic Lane Detection&#xff09;是一种专为交通车道线检测任务设计的深度神经网络架构&#xff0c;由中国科学院计算技术研究所提出&#xff0c;旨在在语义分割框架中增强空间信…

Lerobot框架使用(含本地数据训练)

本文包含从安装环境到完整使用Lerobot框架进行算法复现全流程。 A Install LeRobot 安装miniconda管理python环境 Linux mkdir -p ~/miniconda3 wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh bash ~/minicon…

小红书 web x-s x-t X-Mns 分析

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 逆向分析 cp execjs.compile(open(v…

国产化中间件基本使用_东方通(TongWeb7.0.E.6_P2)

tongweb开发操作文档 1、前期准备 进入官网申请使用,官网地址:https://www.tongtech.com 若提供的安装程序的授权文件已过期,请去官方网站重新申请。 2、安装部署 2.1、下载安装Tongweb 进入官网申请试用,官方会提供响应的嵌入式安装包及试用授权证书(3个月) 申请…

010302-oss_反向代理_负载均衡-web扩展2-基础入门-网络安全

文章目录 1 OSS1.1 什么是 OSS 存储&#xff1f;1.2 OSS 核心功能1.3 OSS 的优势1.4 典型使用场景1.5 如何接入 OSS&#xff1f;1.6 注意事项1.7 cloudreve实战演示1.7.1 配置cloudreve连接阿里云oss1.7.2 常见错误1.7.3 安全测试影响 2 反向代理2.1 正向代理和反向代理2.2 演示…

FREERTOS+LWIP+IAP实现TCP、HTTP、网页访问并固件升级、更新配置 (三)lwip实现httpd服务并在web访问

前言 在前两篇文章中配置freeRTOS和&#xff0c;并实现了TCP、UDP的通信协议&#xff0c;现在终于轮到重头戏lwip的httpd服务&#xff0c;LWIP官方例程中是有很多自带的网页的&#xff0c;但是远远不够满足实际项目的使用需求&#xff0c;因此我也是踩了很多坑&#xff0c;从前…

lighthouse(灯塔)前端性能测试工具

前端性能测试工具之lighthouse灯塔 介绍下载链接使用方法前端性能指标解读 介绍 Lighthouse 是一个开源的自动化工具&#xff0c;用来测试前端页面性能&#xff0c;反馈页面问题以提升页面体验。可以联合谷歌浏览器&#xff0c;作为插件导入&#xff0c;开启后可测试页面性能 …

Ai智能体四:互动式 AI 聊天助手:前端实现

在现代 web 应用中,集成智能对话功能已经成为提升用户体验的重要手段之一。本文将介绍如何通过 Vue 3 和 Element Plus 构建一个高效的 AI 聊天助手界面,并详细讲解其实现原理和功能。 1. 整体架构 该聊天界面分为 左侧边栏 和 右侧内容区域,实现了清晰的布局结构,左侧边…

Spring Boot 3.x 引入springdoc-openapi (内置Swagger UI、webmvc-api)

接触的原因 因开发自己的项目时&#xff0c;写接口文档很繁琐&#xff0c;查到后端都在用swagger等接口工具来记录接口文档&#xff0c;于是学习了一下&#xff0c;本文记录个人配置过程&#xff0c;有问题欢迎指正交流&#x1f601; Swagger&#xff1a; Swagger是一种Rest AP…

OpenWebUI配置异常的外部模型导致页面无法打开

一、使用Ollama关闭OpenAI OpenWebUI自带OpenAI的API设置&#xff0c;且默认是打开的&#xff0c;默认情况下&#xff0c;启动后&#xff0c;会不断的去连https://api.openai.com/v1&#xff0c;但是无法连上&#xff0c;会报错&#xff0c;但是不会影响页面&#xff0c;能正常…

Postman(Apifox)调用WebServicer接口

postman调用WebServicer接口 前言 Postman使用方法Apifox使用方法参数与配置请求代码(当然一般开发会给一个样例)步骤 前言 之前都是使用SoapUI测试WebServicer接口,由于工作所需,需要使用Postman测试工具 Postman使用方法 可以直接在请求里写全部的wsdl地址 ,参数会自动带进…

DeepSeek本地化部署实践:Xinference框架+OpenWebUI实现DeepSeek-r1推理跑在国产GPU之上

近日&#xff0c;我部门从供应商那儿借来一台高算力服务器&#xff0c;用来尝试本地化部署DeepSeek。该服务器型号为ASUS ESC8000A-E11&#xff0c;具体配置如下&#xff1a; CPU&#xff1a;AMD EPYC 7702&#xff08;64核&#xff09;* 2 GPU&#xff1a;&#xff08;天数智…

Android WebRTC集成及JNI性能优化实战指南

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;WebRTC是一个开源项目&#xff0c;旨在实现浏览器间无需插件的实时通信&#xff0c;包括音频、视频通话及数据共享。在Android平台上&#xff0c;其实施涉及使用JNI接口进行Java与C/C代码的交互。本压缩包内容预…

【前端】超链接标签(a标签)之href属性、target属性

文章目录 一、a标签1、href属性&#xff08;1&#xff09;跳转至网络链接页面&#xff08;2&#xff09;跳转至其它工程页面&#xff08;3&#xff09;跳转至本界面 2、target属性 二、感谢观看&#xff01; 一、a标签 a标签即超链接标签&#xff0c;根据名字我们就能知道它是…