算法通关村第十四关—数据流的中位数(黄金)

数据流中中位数的问题

LeetCode295,中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。

例如:[2,3,4]的中位数是3

2,3\]的中位数是(2+3)/2=2.5 实现 MedianFinder 类: * MedianFinder() 初始化 MedianFinder 对象。 * void addNum(int num) 将数据流中的整数 num 添加到数据结构中。 * double findMedian() 返回到目前为止所有元素的中位数。与实际答案相差 10-5 以内的答案将被接受。 ![image.png](https://file.jishuzhan.net/article/1748246899825053698/b7bdb0c9db8eadfd7f4f97632e23e1a6.webp)  分析这是一道比较难的题目了,如果没专门学过,很难在面试时想到。  中位数的题,我们一般都可以用大顶堆+小顶堆来求解,下面我们通过直观的例子解释一下怎么做。 小顶堆(minHeap):存储所有元素中较大的一半,堆顶存储的是其中最小的数。 大顶堆(maxHeap):存储所有元素中较小的一半,堆顶存储的是其中最大的数。  相当于,把所有元素分成了大和小两半,而我们计算中位数,只需要大的那半的最小值和小的那半的最大值即可。比如,我们依次添加\[1,2,3,4,5\],砍成两半之后为\[1,2\]和\[3,4,5\],我们只要能快速的找到2和3即可。  下面看看使用两个堆它们是怎么变化的: 1.添加1,进入到minHeap中,中位数为1:![截屏2024-01-15 07.27.57.png](https://file.jishuzhan.net/article/1748246899825053698/d9317ef20bd61724017e5f71cd8c8b1f.webp) 2.添加2,它比minHeap堆顶元素1大,进入minHeap,同时,minHeap中元素超过了所有元素总和的一半,所以,要平衡一下,分一个给maxHeap,中位数为(1+2)/2.0=1.5:![截屏2024-01-15 07.28.05.png](https://file.jishuzhan.net/article/1748246899825053698/9a05ea8b3f7dd37e8efe4a4c79cea033.webp) 添加3,它比minHeap堆顶元素2大,进入minHeap,中位数为2:![截屏2024-01-15 07.28.13.png](https://file.jishuzhan.net/article/1748246899825053698/e049eab7e918a232a4c1b4b3200920ef.webp) 添加4,它比minHeap堆顶元素2大,进入minHeap,同时,minHeap中元素超过了所有元素总和的一半,所以,要平衡一下,分一个给maxHeap,中位数为(2+3)/2.0=2.5:![截屏2024-01-15 07.28.33.png](https://file.jishuzhan.net/article/1748246899825053698/6cf87860a33db4a588b929a896440e84.webp) 5.添加5,它比minHeap堆J顶元素3大,进入minHeap,中位数为3:![截屏2024-01-15 07.28.40.png](https://file.jishuzhan.net/article/1748246899825053698/9630c17c7f8188895dab7bc3f6bc94a0.webp)  Java中的堆(即优先级队列)是使用完全二叉树实现的,我们这里的图也是以完全二叉树为例。理解了上述的过程,看代码就比较简单了  代码如下 ```java class MedianFinder { PriorityQueue queleft; PriorityQueue queright; public MedianFinder() { queleft = new PriorityQueue((a, b) -> (b - a));//中位数左边是大顶堆 queright = new PriorityQueue();//中位数右边是小顶堆 } public void addNum(int num) { //添加元素 if(queleft.isEmpty() || num <= queleft.peek()){ queleft.offer(num); if(queleft.size() > queright.size() + 1){ //queleft最多比queright多一个元素 queright.offer(queleft.poll()); } } else{ queright.offer(num); if(queright.size() > queleft.size()){ queleft.offer(queright.poll()); } } } public double findMedian() { if(queleft.size() > queright.size()){//奇数情况 return 1.0 * queleft.peek(); } else return (queleft.peek() + queright.peek()) / 2.0; } } ```

相关推荐
飞剑神4 分钟前
qt svg缺失元素, 原因是不支持 rgba
开发语言·qt
Seven9712 分钟前
剑指offer-22、从上往下打印⼆叉树
java
CoovallyAIHub16 分钟前
为什么85%的企业AI项目都失败了?
深度学习·算法·计算机视觉
ankleless17 分钟前
数据结构(03)——线性表(顺序存储和链式存储)
数据结构·考研·链表·顺序表·线性表
KarrySmile19 分钟前
Day8--滑动窗口与双指针--1004. 最大连续1的个数 III,1658. 将 x 减到 0 的最小操作数,3641. 最长半重复子数组
数据结构·算法·双指针·滑动窗口·不定长滑动窗口·最大连续1的个数·最长子数组
zc.ovo23 分钟前
图论水题4
c++·算法·图论
KyollBM28 分钟前
【Luogu】每日一题——Day20. P4366 [Code+#4] 最短路 (图论)
算法·图论
qqxhb29 分钟前
零基础数据结构与算法——第七章:算法实践与工程应用-金融算法
算法·风险评估算法·金融算法·交易策略算法·欺诈检测算法
A尘埃29 分钟前
企业级Java项目金融应用领域——保险系统(补充)
java·金融·保险系统
诗书画唱34 分钟前
【前端面试题】JavaScript 核心知识点解析(第二十二题到第六十一题)
开发语言·前端·javascript