当前位置: 首页 > article >正文

Leetcode 295-数据流的中位数

题解

题解参考自灵茶山艾府

通过中位数将数据分为left和right两部分

比如现在有 6 个数:1,5,6,2,3,4,要计算中位数,可以把这 6 个数从小到大排序,得到 1,2,3,4,5,6,中间 3 和 4 的平均值 3.5 就是中位数。

中位数把这 6 个数均分成了左右两部分,一边是 left=[1,2,3],另一边是 right=[4,5,6]。我们要计算的中位数,就来自 left 中的最大值,以及 right 中的最小值。

随着 addNum 不断地添加数字,我们需要:
保证 left 的大小和 right 的大小尽量相等。规定:在有奇数个数时,left 比 right 多 1 个数。
保证 left 的所有元素都小于等于 right 的所有元素。

只要时时刻刻满足以上两个要求(left中元素<right&&left.size()==right.size()),我们就可以用 left 中的最大值以及 right 中的最小值计算中位数。

算法思想

1.如果当前 left 的大小和 right 的大小相等–>left中数字的个数需要+1
1)如果添加的数字 num 比较大,比如添加 7,那么需要把7 加到 right 中。现在 left 比 right 少 1 个数,不符合前文的规定,所以必须把 right 的最小值从 right 中去掉,添加到 left 中。如此操作后,可以保证 left 的所有元素都小于等于 right 的所有元素。
2)如果添加的数字 num 比较小,比如添加 0,那么需要把 0 加到 left 中。
这两种情况可以合并:无论 num 是大是小,都可以先把 num 加到 right 中,然后把 right 的最小值从 right 中去掉,并添加到 left 中。

算法步骤

最后,我们利用堆结构,高效地执行操作:

1.建立堆 left 是最大堆,right 是最小堆。

2.把数据流中的数据加入堆

脑子里建立如下动态的过程:为了找到添加新数据以后,数据流的中位数,我们让新数据在最大堆和最小堆中都走了一遍。而为了让最大堆的元素多 1 个,我们让从最小堆中又拿出一个元素「送回」给最大堆;

3.计算中位数

如果当前有奇数个元素,中位数是 left 的堆顶。
如果当前有偶数个元素,中位数是 left 的堆顶和 right 的堆顶的平均值。

class MedianFinder {
    private PriorityQueue<Integer> left;
    private PriorityQueue<Integer> right;

    public MedianFinder() {
        //大顶堆存最小的k个数
        left=new PriorityQueue<>((x,y)->(y-x));
        //默认小顶堆 小顶堆存最大的k个数
        right=new PriorityQueue<>();;
    }
    

    public void addNum(int num) {
        //priorityQueue的大小用size
        //left大小=right大小,新来数需要先进到right,再从right里poll出最小值给left
        if(left.size()==right.size()){
            right.offer(num);
            left.offer(right.poll());
        }else{left大小>right大小,新来数需要先进到left,再从left里poll出最大值给right
            left.offer(num);
            right.offer(left.poll());
        }
    }
    
    public double findMedian() {
        //列表数目为偶数个
        if(left.size()==right.size()) return (left.peek()+right.peek())/2.0;
        else return left.peek();
    }
}

在这里插入图片描述


http://www.kler.cn/a/543637.html

相关文章:

  • 遇到的一些GO问题
  • .NET Web-静态文件访问目录浏览
  • MySQL 索引失效案例:字符集不匹配的隐蔽影响
  • vue纯静态实现 视频转GIF 功能(附源码)
  • 本地部署【LLM-deepseek】大模型 ollama+deepseek/conda(python)+openwebui/docker+openwebui
  • LeetCode--32. 最长有效括号【栈和dp】
  • 开源video-subtitle-master 视频转字幕,字幕翻译软件
  • 轻松理解CSS中的float浮动元素
  • 使用 SDKMAN! 在 Mac(包括 ARM 架构的 M1/M2 芯片)安装适配 Java 8 的 Maven
  • 如何从0开始将vscode源码编译、运行、打包桌面APP
  • 使用python tk 做UI,实现的步骤如下:
  • 有哪些免费的SEO软件优化工具
  • 无人机遥感图像拼接及处理实践技术:生态环境监测、农业、林业等领域,结合图像拼接与处理技术,能够帮助我们更高效地进行地表空间要素的动态监测与分析
  • Zabbix-监控SSL证书有效期
  • 智能制造新征程:边缘计算机引领产线维护预测
  • JVM组成
  • 如何取消WPS Excel文件密码
  • 用Python给PDF文件添加密码、取消设置的密码
  • 什么是量子计算?它与经典计算机的本质区别
  • 日常知识点之面试后反思裸写string类
  • 基于Django以及vue的电子商城系统设计与实现
  • 基于深度学习的半导体故障诊断与寿命预测算法研究
  • Java集成Elasticsearch实战商品表增删改查全解析java操作ElasticSearch增删改查
  • java8 list 分页,获取 分页后的 list 和 总页数 的 工具类
  • CST软件无限平面圆孔RCS --- 单站, 单角多频,T和F求解器(远场),去耦平面
  • DeepSeek Coder + IDEA 辅助开发工具