数据流的中位数--堆的典型应用

//其实整个算法的思路就是把 所有数据分为一半大的,一半小的,放在两个堆中
//我们每次取中位数,只需要关心堆顶元素即可
class MedianFinder {
    PriorityQueue<Integer> queMin;
    PriorityQueue<Integer> queMax;

    public MedianFinder() {
        queMin = new PriorityQueue<Integer>((a, b) -> (b - a));
        queMax = new PriorityQueue<Integer>((a, b) -> (a - b));
    }
    
    public void addNum(int num) {
        if (queMin.isEmpty() || num <= queMin.peek()) {
            queMin.offer(num);
            //小根堆的元素最多比大根堆多1
            if (queMax.size() + 1 < queMin.size()) {
                queMax.offer(queMin.poll());
            }
        } else {
            queMax.offer(num);
            //如果数据的个数为奇数,一定是小根堆元素比大根堆元素多
            if (queMax.size() > queMin.size()) {
                queMin.offer(queMax.poll());
            }
        }
    }
    
    public double findMedian() {
        if (queMin.size() > queMax.size()) {
            return queMin.peek();
        }
        return (queMin.peek() + queMax.peek()) / 2.0;
    }
}

posted @ 2021-08-27 11:08  刚刚好。  阅读(41)  评论(0编辑  收藏  举报