Leecode热题100-295.数据流中的中位数

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

  • 例如 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 以内的答案将被接受。

示例 1:

复制代码
输入
["MedianFinder", "addNum", "addNum", "findMedian", "addNum", "findMedian"]
[[], [1], [2], [], [3], []]
输出
[null, null, null, 1.5, null, 2.0]

解释
MedianFinder medianFinder = new MedianFinder();
medianFinder.addNum(1);    // arr = [1]
medianFinder.addNum(2);    // arr = [1, 2]
medianFinder.findMedian(); // 返回 1.5 ((1 + 2) / 2)
medianFinder.addNum(3);    // arr[1, 2, 3]
medianFinder.findMedian(); // return 2.0

提示:

  • -105 <= num <= 105
  • 在调用 findMedian 之前,数据结构中至少有一个元素
  • 最多 5 * 104 次调用 addNumfindMedian

本题我用的是双堆的解法,一个小根堆,一个大根堆,堆的特性要了解,默认情况下顶上是小的,越往下越大(小顶堆)

java 复制代码
class MedianFinder {
    /**先定义两个堆,一个小根(大顶)堆,用来放小的数,一个大跟堆(小顶)用来放大的数
    记住堆默认是小顶堆(大根堆)*/
    PriorityQueue<Integer> minHeap;
    PriorityQueue<Integer> maxHeap;

    public MedianFinder() {
        /**初始化两个堆 */
        minHeap = new PriorityQueue<>((a,b)->b-a);
        maxHeap = new PriorityQueue<>();
    }
    
    public void addNum(int num) {
        /**如果加入的数比maxHeap的顶(这个堆里最大的数)大,就放入小顶堆
        其他情况放入小顶堆*/
        if(minHeap.isEmpty() || num <= minHeap.peek()) {
            minHeap.offer(num);
            /**为了平衡 */
            if(minHeap.size() > maxHeap.size() + 1) {
                maxHeap.offer(minHeap.poll());
            }
        } else {
            maxHeap.offer(num);
            /**为了平衡 */
            if(maxHeap.size() > minHeap.size() + 1) {
                minHeap.offer(maxHeap.poll());
            }
        }
    }
    
    public double findMedian() {
        /**谁的元素多弹出谁的顶 */
        if(maxHeap.size() > minHeap.size()) {
            return maxHeap.peek();
        } else if(maxHeap.size() < minHeap.size()) {
            return minHeap.peek();
        } else {
            /**如果元素一样,弹出他们俩的顶的平均数 */
            return (double)(maxHeap.peek() + minHeap.peek())/2;
        }
    }
}

/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder obj = new MedianFinder();
 * obj.addNum(num);
 * double param_2 = obj.findMedian();
 */
相关推荐
Ali88520几秒前
Python字符串方法速查表大全
前端·python
牛阿大1 分钟前
MPC算法
算法
前端_刘师兄9 分钟前
FAE工程师学习路线-进程
前端
祖力5511 分钟前
快速学会数据结构中的链式队列与循环队列
linux·c语言·数据结构·算法
冰暮流星12 分钟前
javascript之webstorage用法
开发语言·javascript·ecmascript
我一定会有钱14 分钟前
打造完美工作流:Git 配置”一次推送,三端同步”(Gitee/GitCode/GitHub)
开发语言·windows·vscode·搜索引擎·gitlab·github·visual studio code
水无痕simon18 分钟前
5、六大工作模式-1
java
一只叫煤球的猫23 分钟前
Spring AI 2.0 源码解析(一):一次 ChatClient 调用到底经历了什么?
后端·面试·ai编程
原凉是这样的丶26 分钟前
Qwen3.8-27B 开源后,我用双 RTX 4090 跑通了:vLLM 0.27.1、128K 上下文与 MTP 实测
linux·算法
执子念的飞鱼29 分钟前
浏览器直接预览 Pages、Numbers、Keynote:iWork 格式真正难在哪
前端·javascript