leetcode295解法:
class MedianFinder {
private PriorityQueue<Integer> large;
private PriorityQueue<Integer> small;
public MedianFinder() {
// 小顶堆,poll取出的是堆中最小值。java中默认的PriorityQueue时小顶堆
large = new PriorityQueue<>();
// 大顶堆,poll取出的是堆中最大值。注意:return b-a;改变顺序成为大顶堆,因为默认a-b时升序,b-a降序,降序的一个优先队列也就是大顶堆。
small = new PriorityQueue<>((a, b) -> {
return b - a;
});
}
public double findMedian() {
// 如果元素不一样多,多的那个堆的堆顶元素就是中位数
if (large.size() < small.size()) {
return small.peek();
} else if (large.size() > small.size()) {
return large.peek();
}
// 如果元素一样多,两个堆堆顶元素的平均数是中位数
return (large.peek() + small.peek()) / 2.0;
}
//不仅要维护large和small的元素个数之差不超过 1,还要维护large堆的堆顶元素要大于等于small堆的堆顶元素
//small中的元素全部小于等于large,即large堆poll的最小值大于等于small堆poll的最大值
public void addNum(int num) {
if (small.size() >= large.size()) {//想要往large里添加元素,不能直接添加,而是要先往small里添加,然后再把small的堆顶元素加到large中;向small中添加元素同理。
small.offer(num);
large.offer(small.poll());
} else {
large.offer(num);
small.offer(large.poll());
}
}
}
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/