算法通过村第十四关-堆|黄金笔记|中位数

news/2025/2/19 8:46:28/

文章目录

  • 前言
  • 数据流中的中位数的问题
  • 总结


前言


提示:我独自度过了太多的时光,沉默已成一种习惯。 帕瑞尔·马卡姆《夜航西飞》

这个是一个比较难的题目,要不尝试一下看看。

数据流中的中位数的问题

参考题目地址:295. 数据流的中位数 - 力扣(LeetCode)

在这里插入图片描述
在这里插入图片描述

进阶问题:

  1. 如果数据流中所有整数都在0到100范围内呢,你将如何优化你的算法?
  2. 如果数据流中99%的整数都在0到100范围内呢?你将如何优化你的算法?

我们分析一下:

这道题说真的挺难的,如果没有专门的学过,很难再面试中想到。

中位数的题目,我们一般可以采用 大顶堆 + 小顶堆 来求解,下面我们通过直观的例子了解下怎么处理:

小顶堆:存储所有元素中较大的一半,堆顶存储的其实是最小的数。

大顶堆:存储所有元素中较小的一半,堆顶存储的其实是最大的数。

相当于,把所有元素分成大小两半,而我们计算中位数,只需要大的那半的最小值和小的那半的最大值就可以了。

比如:我们依次添加【1,2,3,4,5】,砍成两半为【1,2】和【3,4,5】。我们是需要快速找到 2 和 3 就可以了。

下面我们看看两个堆是怎么变化的:

  1. 添加1,进入minHeap中,中位数为1
  2. 添加2 ,它比minHeap堆顶的元素大1,进入minHeap,minHeap中的元素超过所有元素总和的一半,所以要平衡一下,分给maxHeap,中位数为(1 + 2 )/ 2 = 1.5;
  3. 添加 3 ,它比minHeap堆顶元素2 大,进入minHeap,中位数为2;
  4. 添加4 ,它比minHeap堆顶的元素2大,进入minHeap,minHeap中的元素超过所有元素总和的一半,所以要平衡一下,分给maxHeap,中位数为(2+ 3 )/ 2 = 2.5;
  5. 添加 5,它比minHeap堆顶元素3 大,进入minHeap,中位数为3;

Java中堆(即使优先队列)是使用完全二叉树实现的。理解以下,我们看代码怎么做,代码写起来比较简单,但是实现起来还挺麻烦的。

class MedianFinder {// 这里小顶堆 存储较大的一半(最小值在堆顶PriorityQueue<Integer> minHeap;// 这里大顶堆 存储较小的一半(最大值在堆顶PriorityQueue<Integer> maxHeap;public MedianFinder() {minHeap = new PriorityQueue<>();maxHeap = new PriorityQueue<>((a,b) -> b - a);}public void addNum(int num) {// 小顶堆存储大的元素,num只要大于元素中最小的,就入堆if(minHeap.isEmpty() || num > minHeap.peek()){minHeap.offer(num);if(minHeap.size() - maxHeap.size() > 1){maxHeap.offer(minHeap.poll());}}else{maxHeap.offer(num);// 可以确保多的那个元素一定在minHeapif(maxHeap.size() - minHeap.size() > 0){minHeap.offer(maxHeap.poll());}}}public double findMedian() {if(minHeap.size() > maxHeap.size()){return minHeap.peek();}else if(minHeap.size() < maxHeap.size()){return maxHeap.peek();}else{return (minHeap.peek() + maxHeap.peek()) / 2.0;}}
}/*** Your MedianFinder object will be instantiated and called as such:* MedianFinder obj = new MedianFinder();* obj.addNum(num);* double param_2 = obj.findMedian();*/

总结

提示:堆的经典应用;大顶堆小顶堆;中位数问题;特殊解法;优先队列(priority):


如果有帮助到你,请给题解点个赞和收藏,让更多的人看到 ~ ("▔□▔)/ 如有不理解的地方,欢迎你在评论区给我留言,我都会逐一回复 ~ 也欢迎你 关注我 ,喜欢交朋友,喜欢一起探讨问题。

在这里插入图片描述


http://www.ppmy.cn/news/1157444.html

相关文章

Python3无法调用Sqlalchemy解决(mysqldb)

原因 在安装Sqlalchemy后运行程序报错 无法导入mysqldb&#xff0c;缺失模块 ImportError: No module named ‘MySQLdb’ 既然缺少 MySQLdb 这个模块&#xff0c;尝试按照正常的想法执行 pip install MySQLdbpip install mysql-python 应该能解决&#xff0c;但是却找不到…

人大与加拿大女王大学金融硕士——人生最好的贵人,就是努力向上的自己

![在这个经济飞速发展的时代&#xff0c;职场竞争愈发激烈&#xff0c;如果一味的安于现状&#xff0c;那么很有可能被社会所淘汰。近年来&#xff0c;金融行业的发展更是迅速&#xff0c;对于高端人才的需求也越来越大。所以对于从事这行的工作者来说&#xff0c;在职研究生就…

GitHub Action 通过SSH 自动部署到云服务器上

准备 正式开始之前&#xff0c;你需要掌握 GitHub Action 的基础语法&#xff1a; workflow &#xff08;工作流程&#xff09;&#xff1a;持续集成一次运行的过程&#xff0c;就是一个 workflow。name: 工作流的名称。on: 指定次工作流的触发器。push 表示只要有人将更改推…

Latex 通过\item控制编号

\item通常用于 1 论文写作中的hightlight 2 或一些需要缩进的场景 具体实现 \item 或\item[]在方括号里面添加1&#xff09;、 (1)来控制

开路、断路和短路区别

文章目录 开路和断路击穿电源短路、用电器短路、对地短路和对电源短路 开路和断路 开路和断路是电路中两种用于描述电流流动情况的状态。 两者易混淆&#xff0c;常被混淆使用&#xff0c;但是它们还是有所不同。 开路表示电路中存在一个断链&#xff0c;电流无法从一个点流到…

代理IP可以用于哪些实际场景?遇到问题如何解决

代理IP的应用场景非常广泛&#xff0c;可以在不同领域提供许多有用的功能。以下是关于代理IP应用场景的详细扩充&#xff0c;包括每个场景的优势和应用建议&#xff0c;以及在使用代理IP时可能遇到的问题和应对方法。 1.价格监控&#xff1a; 商业竞争很大程度上是价格竞争。在…

用Flask构建一个AI翻译服务

缘起 首先&#xff0c;看一段代码&#xff0c;只有几行Python语句却完成了AI翻译的功能。 #!/usr/bin/python3import sys from transformers import MarianMTModel, MarianTokenizerdef translate(word_list):model_name "Helsinki-NLP/opus-mt-en-zh"tokenizer …

Java 全栈体系(四)

第一章 Java 基础语法 十、IDEA 5. IDEA 中类的相关操作 5.1 类的相关操作 新建类文件 删除类文件 修改类文件 5.2 新建类文件 所有的 Java 代码都会写在 src 文件夹当中。 所以&#xff0c;右键点击 src&#xff0c;选择 new&#xff0c;点击 Java Class。 输入类名&…