堆----3.数据流的中位数

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

/**

基础数据结构:

大顶堆:完全二叉树,任一结点>=其左右孩子;小顶堆:完全二叉树,任一结点<=其左右孩子

大体做法:

同时使用一个大顶堆与一个小顶堆,在插入元素时进行限制。

大顶堆元素最大值 <= 小顶堆元素最小值,且两堆元素相差个数不超过1

若两堆元素个数相等,则中位数:大顶堆堆顶元素(大顶堆最大值)与小顶堆堆顶元素(小顶堆最小值)的平均数

若大顶堆的元素更多,则中位数:大顶堆堆顶元素

若小顶堆的元素更多,则中位数:小顶堆堆顶元素(此处插入方式不存在该情况)

插入过程:

首先插入元素时统一直接插入大顶堆(小顶堆也可以)

再把大顶堆的堆顶元素(大顶堆最大元素)弹出,插入到小顶堆;(即先将元素插入大顶堆,再把大顶堆最大的元素移到小顶堆,实现了大顶堆元素最大值 <= 小顶堆元素最小值)

此时进行判断,若小顶堆元素更多,则将小顶堆堆顶元素(小顶堆最小元素)弹出,插入到大顶堆中;

(由于为了实现大顶堆元素最大值 <= 小顶堆元素最小值,将大顶堆的最大元素移到了小顶堆,此时必须要平衡两堆元素,否则元素会全部留在小顶堆中)

注意事项:

经过调整后要么两堆元素数量相等,要么大顶堆元素更多,不存在小顶堆元素更多的情况。

*/

java 复制代码
/**
    基础数据结构:
            大顶堆:完全二叉树,任一结点>=其左右孩子;小顶堆:完全二叉树,任一结点<=其左右孩子
    大体做法:
            同时使用一个大顶堆与一个小顶堆,在插入元素时进行限制。
            大顶堆元素最大值 <= 小顶堆元素最小值,且两堆元素相差个数不超过1
            若两堆元素个数相等,则中位数:大顶堆堆顶元素(大顶堆最大值)与小顶堆堆顶元素(小顶堆最小值)的平均数
            若大顶堆的元素更多,则中位数:大顶堆堆顶元素
            若小顶堆的元素更多,则中位数:小顶堆堆顶元素(此处插入方式不存在该情况)
    插入过程:
            首先插入元素时统一直接插入大顶堆(小顶堆也可以)
            再把大顶堆的堆顶元素(大顶堆最大元素)弹出,插入到小顶堆;(即先将元素插入大顶堆,再把大顶堆最大的元素移到小顶堆,实现了大顶堆元素最大值 <= 小顶堆元素最小值)
            此时进行判断,若小顶堆元素更多,则将小顶堆堆顶元素(小顶堆最小元素)弹出,插入到大顶堆中;
            (由于为了实现大顶堆元素最大值 <= 小顶堆元素最小值,将大顶堆的最大元素移到了小顶堆,此时必须要平衡两堆元素,否则元素会全部留在小顶堆中)
    注意事项:
            经过调整后要么两堆元素数量相等,要么大顶堆元素更多,不存在小顶堆元素更多的情况。
*/
class MedianFinder {
    
    //大顶堆,左半区,存较小的元素
    private PriorityQueue<Integer> left_maxHeap;
    //小顶堆,右半区,存较大的元素
    private PriorityQueue<Integer> right_minHeap; 

    public MedianFinder() {
        //优先队列实现大/小顶堆
        left_maxHeap = new PriorityQueue<>((a,b) -> b - a); //大顶堆,自定义比较器
        right_minHeap = new PriorityQueue<>(); //默认为小顶堆
    }
    
    public void addNum(int num) {
        //直接插入大顶堆
        left_maxHeap.offer(num);

        //保证 大顶堆元素最大值 <= 小顶堆元素
        right_minHeap.offer(left_maxHeap.poll());

        //平衡两堆元素个数 要么两堆元素个数相等,要么大顶堆比小丁堆多一个元素
        if(right_minHeap.size() > left_maxHeap.size()) {
            left_maxHeap.offer(right_minHeap.poll());
        }
    }
    
    public double findMedian() {
        //两堆元素相等 大顶堆堆顶元素(大顶堆最大值)与小顶堆堆顶元素(小顶堆最小值)的平均值
        if(right_minHeap.size() == left_maxHeap.size()) {
            return (right_minHeap.peek() + left_maxHeap.peek()) / 2.0;
        } 

        //要么两堆元素个数相等,要么大顶堆比小顶堆多一个元素
        return left_maxHeap.peek();
    }
}

/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder obj = new MedianFinder();
 * obj.addNum(num);
 * double param_2 = obj.findMedian();
 */
相关推荐
翻斗花园刘大胆2 分钟前
JavaSE之String 与 StringBuilder 全面解析(附实例代码)
java·开发语言·jvm·git·java-ee·intellij-idea·html5
Poppy .^0^3 分钟前
Tomcat 全面指南:从目录结构到应用部署与高级配置
java·tomcat
jtymyxmz5 分钟前
刷题日记0902
算法·leetcode
一 乐8 分钟前
在线宠物用品|基于vue的在线宠物用品交易网站(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·|在线宠物用品交易网站
shepherd11111 分钟前
深入解析Flowable工作流引擎:从原理到实践
java·后端·工作流引擎
l56575811 分钟前
第五十天(SpringBoot栈&Actuator&Swagger&HeapDump&提取自动化)
java·spring boot·spring
kyle~27 分钟前
海康摄像头开发---标准配置结构体(NET_DVR_STD_CONFIG)
运维·服务器·c++·算法·microsoft·海康威视
古译汉书28 分钟前
蓝桥杯算法之基础知识(4)
开发语言·python·算法·蓝桥杯
睡不醒的kun30 分钟前
leetcode算法刷题的第二十四天
数据结构·c++·算法·leetcode·职场和发展·贪心算法
荣淘淘38 分钟前
互联网大厂Java面试三大回合全解析:从语言特性到性能安全
java·安全·面试·性能优化·互联网·多线程·语言特性