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();
 */
相关推荐
真的很上进几秒前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html
web130933203987 分钟前
vue elementUI form组件动态添加el-form-item并且动态添加rules必填项校验方法
前端·vue.js·elementui
呆呆的猫10 分钟前
【LeetCode】227、基本计算器 II
算法·leetcode·职场和发展
Tisfy12 分钟前
LeetCode 1705.吃苹果的最大数目:贪心(优先队列) - 清晰题解
算法·leetcode·优先队列·贪心·
州周16 分钟前
Ftp目录整个下载
linux·服务器·数据库
NiNg_1_23428 分钟前
Echarts连接数据库,实时绘制图表详解
前端·数据库·echarts
余额不足1213832 分钟前
C语言基础十六:枚举、c语言中文件的读写操作
linux·c语言·算法
众拾达人32 分钟前
Android自动化测试实战 Java篇 主流工具 框架 脚本
android·java·开发语言
皓木.35 分钟前
Mybatis-Plus
java·开发语言
不良人天码星35 分钟前
lombok插件不生效
java·开发语言·intellij-idea