【Java语言】剑指offer系列之堆、优先队列、排序----数据流中的中位数

题目描述
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

分析:可以使用优先队列的大小顶堆来进行排序,进而获得中位数。

具体代码实现如下:

import java.util.*;
public class Solution {

    /*
    利用优先队列的大小顶堆来实现中位数,大顶堆保存较小的数(那么它的头元素(堆顶)即为较小数中的最大数),
    小顶堆保存较大的数(那么它的头元素(堆顶)即为较大数中的最小数)。设共有N=m+n个元素,在添加元素时要保证大小顶堆各一半:
    当N为奇数时:m=n+1=(N+1)/2 (m表示小顶堆里面的元素个数)
    当N为偶数时:m=n=N/2       (n表示大顶堆里面的元素个数)
    故,当m=n时,中位数为:(小顶堆的堆顶元素+大顶堆的堆顶元素)/2
       当m≠n时,中位数为:小顶堆的堆顶元素
    */
    PriorityQueue<Integer> min = new PriorityQueue<>();;// 小顶堆
    PriorityQueue<Integer> max = new PriorityQueue<>((x,y) -> (y - x));// 大顶堆
    public void Insert(Integer num) {// 要保证大小顶堆中的元素之差小于等于1
        if(min.size() == max.size()){//元素最终需要放入小顶堆中
            max.offer(num);// 先放入大顶堆中进行排序
            min.offer(max.poll());// 再将大顶堆中堆顶的元素(较小数中最大的元素)放入小顶堆
        }else{// 元素最终放入大顶堆中
            min.offer(num);// 先放入小顶堆进行排序,比较大小,堆顶为较小数中的最大值
            max.offer(min.poll());// 然后再将小顶堆中堆顶的元素(较大数中最小的元素)放入大顶堆
        }
    }

    public Double GetMedian() {// 如果大小顶堆长度不等,则中位数存在于小顶堆的堆顶,否则存在于两个堆顶元素除以2
        return min.size() == max.size() ? (min.peek() + max.peek()) / 2.0 : (double)min.peek();
    }


}

人生若只如初见,何事秋风悲画扇。
等闲变却故人心,却道故人心易变。
-----------纳兰性德

小白寄语:学如逆水行舟,不进则退。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值