维护两个优先队列:小根堆 & 大根堆
小根堆:存放右半边最小值元素
大根堆:存饭左半边最大值元素
保持两个优先队列大小始终相等或相差 1
添加元素:如果需要加入大根堆中,则需要先插入小根堆,然后弹出小根堆顶元素加入大根堆中,这样才可以保证maxQ 中所有元素 < minQ 中的所有元素;反之亦然
返回中位数:如果两个优先队列大小相等,则返回堆顶元素和的平均值;如果不相等,则返回元素值更多的堆顶
xclass MedianFinder { // 小根堆:存放右半边大值元素 Queue<Integer> minQ; // 大根堆:存放左半边小值元素 Queue<Integer> maxQ;
public MedianFinder() { minQ = new PriorityQueue<>(); maxQ = new PriorityQueue<>((o1, o2) -> (o2 - o1)); } public void addNum(int num) { // 始终保持 maxQ 中所有元素 < minQ 中的所有元素 if (maxQ.size() <= minQ.size()) { minQ.offer(num); maxQ.offer(minQ.poll()); } else { maxQ.offer(num); minQ.offer(maxQ.poll()); } } public double findMedian() { if (minQ.size() == maxQ.size()) return (minQ.peek() + maxQ.peek()) / 2.0; return minQ.size() > maxQ.size() ? minQ.peek() : maxQ.peek(); }}