思路:
参考DISCUSS。
通过大顶堆+小顶堆来实现。经典。
大顶堆中堆顶的元素如果小于小顶堆堆顶的元素,则大顶堆中的所有元素就都小于小顶堆中的所有元素。如果再保证maxHeap.size()==minHeap.size() 或者 maxHeap.size() == minHeap.size() + 1的话,就使用两个堆顶元素就可以直接计算出中位数。
所以得出:
- 如果
maxHeap.size()==minHeap.size()
,(大顶堆堆顶元素+小顶堆堆顶元素)/2就是中位数; - 如果
maxHeap.size() == minHeap.size() + 1
,大顶堆堆顶元素就是中位数;
java code:
class MedianFinder {
PriorityQueue<Long> maxHeap;
PriorityQueue<Long> minHeap;
public MedianFinder() {
maxHeap = new PriorityQueue<Long>(Collections.reverseOrder());//change to a maximum heap
minHeap = new PriorityQueue<Long>();//heap is a minimal heap by default
}
// Adds a number into the data structure.
public void addNum(int num) {
maxHeap.add((long)num);
minHeap.add(maxHeap.poll());
if(maxHeap.size() < minHeap.size()) {
maxHeap.add(minHeap.poll());
}
}
// Returns the median of current data stream
public double findMedian() {
if(maxHeap.size() == minHeap.size()) {
return (maxHeap.peek() + minHeap.peek()) / 2.0;
}else {
return maxHeap.peek();
}
}
};
// Your MedianFinder object will be instantiated and called as such:
// MedianFinder mf = new MedianFinder();
// mf.addNum(1);
// mf.findMedian();