
思路源于
【大厂程序员带你刷力扣】【LeetCode 295】数据流的中位数|大根堆|小根堆
创建大根堆和小根堆,保证大根堆和小根堆的数量差异在1之内并且大根堆的最大值总是不超过小根堆的最小值(大根堆的所有元素都小于等于小根堆的所有元素,这样就将所有的元素一分为2了),这样中位数就只与大根堆的最大值和小根堆的最小值有关
添加元素时先扔到大根堆,如果大根堆的最大大于小根堆的最小,那么把这个最大送给小根堆,之后如果大根堆的元素比小根堆多2那么就将小根堆的元素送给大根堆,反之同理
返回元素时如果大根堆比小根堆多1说明总体是奇数只需返回大根堆的最大值,小根堆多1那结果就是小根堆的最小值,二者相等则取两者平均值
java
class MedianFinder {
private PriorityQueue<Integer> maxHeap;
private PriorityQueue<Integer> minHeap;
public MedianFinder() {
maxHeap = new PriorityQueue<>(Comparator.reverseOrder());
minHeap = new PriorityQueue<>();
}
public void addNum(int num) {
maxHeap.add(num);
if (!maxHeap.isEmpty() && !minHeap.isEmpty() && maxHeap.peek() > minHeap.peek()) {
minHeap.add(maxHeap.poll());
}
if (maxHeap.size() == minHeap.size() + 2) {
minHeap.add(maxHeap.poll());
}
if (maxHeap.size() == minHeap.size() - 2) {
maxHeap.add(minHeap.poll());
}
}
public double findMedian() {
if(maxHeap.size()==minHeap.size()+1)
return maxHeap.peek();
else if(maxHeap.size()==minHeap.size()-1)
return minHeap.peek();
else
return (maxHeap.peek() + minHeap.peek()) / 2.0;
}
}