leetcode295.数据流的中位数

中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。

例如 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

解决方案

双堆法

  1. 我们创建一个大根堆和一个小根堆,分别用来存储数据流中较小的一半和较大的一半元素。然后,我们定义一个变量median来保存当前的中位数。
  2. 每当有一个新的元素num加入到数据流中时,我们需要更新两个堆和median。具体步骤如下:
  3. 如果num小于或等于median,那么我们把num加入到大根堆中;否则,我们把num加入到小根堆中。
  4. 如果两个堆中的元素个数相差超过1,那么我们需要调整两个堆的大小,使得它们相差不超过1。具体方法是:如果大根堆比小根堆多2个元素,那么我们把大根堆的最大元素移动到小根堆中;如果小根堆比大根堆多2个元素,那么我们把小根堆的最小元素移动到大根堆中。
  5. 如果两个堆中的元素个数相等,那么median就是两个堆顶元素的平均值;如果其中一个堆多一个元素,那么median就是该多出来的元素。
  6. 这样,每次添加一个新元素后,我们都可以在O(log n)的时间内更新两个堆和median,并且在O(1)的时间内返回当前的中位数。

有序集合

  • 用有序集合解决这个问题的方法,就是把数据流中的整数 num 作为有序集合的成员,每次添加一个新的整数 num 时,只需要找到它在有序集合中的正确位置。然后,要找到所有元素的中位数,只需要根据有序集合的大小,取出中间一个或两个成员,并计算它们的平均值。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值