数据流的中位数

题目链接

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

思路

利用数据结构的堆来解决这个问题 ------ 大根堆 小根堆

大根堆里面的内容 特征是 父节点的值 大于或者等于 其子节点的值

小根堆里面的内容 特征是 父节点的值 小于或者等于 其子节点的值

大根堆里面数据 其实就是 其中位数的 左边 的 ------ 比中位数小的内容

小根堆里面数据 其实就是 其中位数的 右边 的 ------ 比中位数大的内容

我们维护这俩个堆,大根堆可以比小根堆多一个,此时 数据是 奇数 中位数 是大根堆的堆顶,当大根堆和小根堆数据量一致时,代表此时数据是 偶数,返回 大根堆的堆顶 和 小根堆 的堆顶 俩个数字除以2 就是最后的内容

c++ java python 都有现成的数据结构可以使用,

js需要手写(参考了一个题解的写法)

代码:

javascript 复制代码
var MedianFinder = function() {
    function createHeap(type) { // type: 0-最小堆, 1-最大堆
        const h = [null]; // 索引从1开始,方便计算
        let size = 0;

        function push(val) {
            h[++size] = val;
            up(size);
        }

        function up(u) {
            // 当还有父节点且需要交换时
            while (u >> 1 >= 1) {
                const parent = u >> 1;
                // 最小堆:子节点 < 父节点 时交换
                // 最大堆:子节点 > 父节点 时交换
                if ((type === 0 && h[u] < h[parent]) || 
                    (type === 1 && h[u] > h[parent])) {
                    [h[u], h[parent]] = [h[parent], h[u]];
                    u = parent;
                } else {
                    break;
                }
            }
        }

        function down(u) {
            while (u * 2 <= size) {
                let t = u;
                const left = u * 2;
                const right = u * 2 + 1;
                
                // 和左子节点比较
                if ((type === 0 && h[t] > h[left]) || 
                    (type === 1 && h[t] < h[left])) {
                    t = left;
                }
                // 和右子节点比较
                if (right <= size && (
                    (type === 0 && h[t] > h[right]) || 
                    (type === 1 && h[t] < h[right]))) {
                    t = right;
                }
                
                if (t !== u) {
                    [h[u], h[t]] = [h[t], h[u]];
                    u = t;
                } else {
                    break;
                }
            }
        }

        function pop() {
            if (size === 0) return null;
            const top = h[1];
            h[1] = h[size--];
            down(1);
            return top;
        }

        function peek() {
            return h[1];
        }

        function getSize() {
            return size;
        }

        function isEmpty() {
            return size === 0;
        }

        return {
            push,
            pop,
            peek,
            getSize,
            isEmpty
        };
    }

    // 最大堆(存较小的一半)
    this.maxHeap = createHeap(1);
    // 最小堆(存较大的一半)
    this.minHeap = createHeap(0);
};

MedianFinder.prototype.addNum = function(num) {
    // 标准解法:先加入最大堆,然后把最大堆的最大值移到最小堆
    if (this.maxHeap.isEmpty() || num <= this.maxHeap.peek()) {
        this.maxHeap.push(num);
    } else {
        this.minHeap.push(num);
    }
    
    // 平衡两个堆的大小
    // 最大堆可以比最小堆多一个元素,但不能少
    if (this.maxHeap.getSize() > this.minHeap.getSize() + 1) {
        this.minHeap.push(this.maxHeap.pop());
    } else if (this.minHeap.getSize() > this.maxHeap.getSize()) {
        this.maxHeap.push(this.minHeap.pop());
    }
};

MedianFinder.prototype.findMedian = function() {
    if (this.maxHeap.getSize() > this.minHeap.getSize()) {
        // 奇数个元素,最大堆多一个
        return this.maxHeap.peek();
    } else {
        // 偶数个元素,取平均值
        return (this.maxHeap.peek() + this.minHeap.peek()) / 2;
    }
};
相关推荐
weixin_460443563 小时前
2026年新修订《网络安全法》实施:Java私有化考试系统如何做好SBOM、漏洞治理与安全升级?
java·开发语言·在线考试系统·企业培训考试系统·宏远培训考试系统·国企培训考试系统·国产化培训系统
子兮曰3 小时前
把 649 种文件格式塞进一个网页里:一个「文件不出浏览器」的预览器
前端·javascript·后端
Cc.Y6 小时前
Java零基础入门:可变字符串与包装类:StringBuilder、StringBuffer 与 通讯录管理系统实战
java·开发语言·python
paopaokaka_luck6 小时前
基于springboot+vue的智慧家政管理系统(AI问答、 WebSocket实时沟通、ECharts运营分析、订单规则与服务追踪)
java·javascript·spring boot·数据分析·echarts·mybatis
sm_926787056 小时前
RFID 标签打印的技术实现要点与二次开发实践
java·大数据·前端·c++·编辑器
阿森_dev6 小时前
2027 届毕设选题怎么选:30 个 Java 方向选题的实现难度排序
java·开发语言·spring boot·毕业设计·课程设计
by209996 小时前
C++ 多态:同一个基类接口,调用不同的函数
开发语言·c++·经验分享·多态
笔墨登场说说6 小时前
flink bin/start-cluster.sh 帮我做成开机启动
开发语言·python
Sarvartha6 小时前
Lambda 表达式和函数式接口
java·开发语言
IMPYLH7 小时前
HTML 的 <video> 元素
前端·html