leetcode 295. 数据流的中位数

2019-04-24  本文已影响0人  topshi

题目描述

中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。
相关话题: 堆、设计    难度: 困难
例如,
[2,3,4] 的中位数是 3
[2,3] 的中位数是 (2 + 3) / 2 = 2.5
设计一个支持以下两种操作的数据结构:

示例:
addNum(1)
addNum(2)
findMedian() -> 1.5
addNum(3)
findMedian() -> 2

进阶:

  1. 如果数据流中所有整数都在 0 到 100 范围内,你将如何优化你的算法?
  2. 如果数据流中 99% 的整数都在 0 到 100 范围内,你将如何优化你的算法?

思路:

至于一个数据来临应该加到哪个堆:当num < maxHeap.peek(),加入到maxHeap中,否则加入到minHeap,这样才不会破坏堆顶的相邻关系。任意一个堆的大小比另一个堆大2,将较多元素的堆的堆顶弹出来加到较少元素的堆中。

class MedianFinder {
    private PriorityQueue<Integer> minHeap;
    private PriorityQueue<Integer> maxHeap;
    /** initialize your data structure here. */
    public MedianFinder() {
        this.minHeap = new PriorityQueue<Integer>();
        this.maxHeap = new PriorityQueue<Integer>(new Comparator<Integer>(){
            public int compare(Integer t1, Integer t2){
                return t2 - t1;
            }
        });
    }
    public void addNum(int num) {
        if(maxHeap.size() > 0 && num < maxHeap.peek()){
            maxHeap.offer(num);
        }else{
            minHeap.offer(num);
        }
        if(minHeap.size() - maxHeap.size() > 1){
            maxHeap.offer(minHeap.poll());
        }else if(maxHeap.size() - minHeap.size() > 1){
            minHeap.offer(maxHeap.poll());
        }
    }
    public double findMedian() {
        if(minHeap.size() > maxHeap.size()){
            return minHeap.peek();
        }else if(maxHeap.size() > minHeap.size()){
            return maxHeap.peek();
        }else{
            return (maxHeap.peek() + minHeap.peek()) / 2.0;
        }
        
    }
}
/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder obj = new MedianFinder();
 * obj.addNum(num);
 * double param_2 = obj.findMedian();
 */
上一篇下一篇

猜你喜欢

热点阅读