美文网首页
面试题41_数据流中的中位数

面试题41_数据流中的中位数

作者: shenghaishxt | 来源:发表于2020-02-15 13:46 被阅读0次

    题目描述

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

    题解

    将所有数据分为两半,分别放入一个最大堆和一个最小堆中。最大堆用来存较小的数,最小堆用来存较大的数。这时候中位数就是最大堆的根节点和最小根的根节点的平均数。

    这种方法一个最关键的点是:在每次插入数据时,不能直接插入,而是需要取另一个堆的根节点进行插入。这样,每次插入最小堆的是当前最大堆中最大的元素,每次插入最大堆的是当前最小堆中最小的元素,这样才能保证最大堆中的值全部小于最小堆中的值。

    PriorityQueue<Integer> minHeap;
    PriorityQueue<Integer> maxHeap;
    
    Solution() {
        minHeap = new PriorityQueue<>();
        maxHeap = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2.compareTo(o1);
            }
        });
    }
    
    public void Insert(Integer num) {
        if (minHeap.size() == maxHeap.size()) {
            minHeap.offer(num);
            if (!minHeap.isEmpty()) maxHeap.offer(minHeap.poll());
        }
        else {
            maxHeap.offer(num);
            if (!maxHeap.isEmpty()) minHeap.offer(maxHeap.poll());
        }
    }
    
    public Double GetMedian() {
        if (minHeap.isEmpty() && maxHeap.isEmpty())
            return 0.0;
        if (!minHeap.isEmpty() && !maxHeap.isEmpty() && minHeap.size() == maxHeap.size())
            return (double) (minHeap.peek() + maxHeap.peek()) / 2;
        else if (!maxHeap.isEmpty())
            return (double) maxHeap.peek();
        else return 0.0;
    }
    

    相关文章

      网友评论

          本文标题:面试题41_数据流中的中位数

          本文链接:https://www.haomeiwen.com/subject/isgefhtx.html