双堆法求数据流的中位数

代码逻辑

这道题的关键在于如何在动态添加元素的过程中,快速找到中位数。

我们可以用一个大顶堆 (maxHeap)存储较小的一半元素,堆顶是这部分的最大值 和一个小顶堆 (minHeap)存储较大的一半元素,堆顶是这部分的最小值,这样的话,中位数就在两个堆的堆顶附近!

1.添加元素

添加新元素时, 如果大顶堆为空,或新元素 ≤ 大顶堆堆顶 → 放入大顶堆,否则 → 放入小顶堆。

如果两个堆的大小差为 2,就从元素多的堆中取出堆顶,放入另一个堆。

2.查找中位数

如果两个堆大小相等 → 中位数 = (大顶堆堆顶 + 小顶堆堆顶) / 2;

如果大小不等 → 中位数 = 元素多的那个堆的堆顶。

代码实现

java 复制代码
class MedianFinder {
    private PriorityQueue<Integer> maxHeap;  // 大顶堆,存储较小的一半
    private PriorityQueue<Integer> minHeap;  // 小顶堆,存储较大的一半
    
    public MedianFinder() {
        // Java的PriorityQueue默认是小顶堆,需要自定义比较器实现大顶堆
        maxHeap = new PriorityQueue<>((a, b) -> b - a);
        minHeap = new PriorityQueue<>((a, b) -> a - b);
    }
    
    public void addNum(int num) {
        // 决定新元素放入哪个堆
        if (maxHeap.isEmpty() || maxHeap.peek() >= num) {
            maxHeap.add(num);
        } else {
            minHeap.add(num);
        }
        // 调整两个堆的平衡
        balance();
    }
    
    public double findMedian() {
        if (maxHeap.size() == minHeap.size()) {
            // 偶数个元素,返回两个堆顶的平均值
            return (double) (maxHeap.peek() + minHeap.peek()) / 2;
        } else {
            // 奇数个元素,返回元素多的那个堆的堆顶
            return maxHeap.size() > minHeap.size() ? maxHeap.peek() : minHeap.peek();
        }
    }
    
    private void balance() {
        // 如果两个堆的大小差为2,需要调整
        if (Math.abs(maxHeap.size() - minHeap.size()) == 2) {
            if (maxHeap.size() > minHeap.size()) {
                minHeap.add(maxHeap.poll());
            } else {
                maxHeap.add(minHeap.poll());
            }
        }
    }
}
相关推荐
开开心心就好2 天前
轻量级PDF阅读器,仅几M大小打开秒开
linux·运维·服务器·安全·pdf·1024程序员节·oneflow
学传打活5 天前
【边打字.边学昆仑正义文化】_12_生命价值的体现(1)
微信公众平台·1024程序员节·汉字·昆仑正义文化
开开心心就好6 天前
小巧绿色免费关机工具,支持定时倒计时
linux·运维·服务器·安全·powerpoint·1024程序员节·foxmail
开开心心就好7 天前
跨平台高速下载工具,支持浏览器功能强大
运维·服务器·windows·pdf·旅游·媒体·1024程序员节
开开心心就好25 天前
内存清理软件灵活设置,自动阈值快捷键清
运维·服务器·windows·pdf·harmonyos·risc-v·1024程序员节
学传打活1 个月前
【边打字.边学昆仑正义文化】_5_宇宙物种创造简史(1)
微信公众平台·1024程序员节·汉字·昆伦正义文化
xcLeigh1 个月前
打破机房围墙:VMware+cpolar构建跨网络虚拟实验室
vmware·内网穿透·cpolar·实验室·远程访问·1024程序员节
开开心心就好1 个月前
免费轻量电子书阅读器,多系统记笔记听书
linux·运维·服务器·安全·ddos·可信计算技术·1024程序员节
unable code1 个月前
流量包取证-大流量分析
网络安全·ctf·misc·1024程序员节·流量包取证