42.数据流中的中位数

如何得到一个数据流中的中位数?

如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。

如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。

数据范围:

数据流中读入的数据总数 [1,1000]。

样例:

输入:1, 2, 3, 4
输出:1,1.5,2,2.5
解释:每当数据流读入一个数据,就进行一次判断并输出当前的中位数。

代码:

class Solution {
    //小顶堆,存储较大的一半数字(堆顶是较大数中的最小值)
    PriorityQueue<Integer> minHeap = new PriorityQueue<>();
    //大顶堆,存储较小的一半数字(堆顶是较小数中的最大值)
    PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
    public void insert(Integer num) {
        //如果小顶堆为空,或者数字大于小顶堆的最小值(即属于较大的一半),将该数字放入较大的一半
        if(minHeap.isEmpty()||num>minHeap.peek())minHeap.offer(num);
        //否则放入较小的一半
        else maxHeap.offer(num);
        //平衡两个堆的大小,确保它们的大小差不超过1
        //如果较大的一半比较小的一半多2个元素,将较大的一半的最小值移到较小的一半
        if(minHeap.size()>maxHeap.size()+1)maxHeap.offer(minHeap.poll());
        //如果较小的一半比较大的一半多,将较小的一半的最大值移到较大的一半
        else if(maxHeap.size()>minHeap.size())minHeap.offer(maxHeap.poll());
    }

    public Double getMedian() {
        //如果两堆大小相等,中位数是两堆顶的平均值
        if(minHeap.size() == maxHeap.size())return (minHeap.peek()+maxHeap.peek())/2.0;
        //否则中位数在较大一半的堆顶(因为较大一半可能多1个元素)
        else return minHeap.peek()*1.0;
    }
}
posted @ 2025-05-28 10:08  回忆、少年  阅读(11)  评论(0)    收藏  举报