数据流的中位数--堆的典型应用
//其实整个算法的思路就是把 所有数据分为一半大的,一半小的,放在两个堆中
//我们每次取中位数,只需要关心堆顶元素即可
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;
}
}
我有一壶酒
足以慰风尘
尽倾江海里
赠饮天下人