题目
剑指 Offer 41. 数据流中的中位数 - 力扣(LeetCode)
思路
维护一个大根堆和一个小根堆(两个堆大小相差不超过1),其中大根堆存储较小的那半部分数据,小根堆存储较大的那半部分数据,因此大根堆的堆顶和小根堆的堆顶可以代表中位数的取值。
需要注意:
- 在两个堆大小不一样的时候,元素多的那个堆的堆顶是中位数,否则是两个堆的堆顶的平均值。
- 规定小根堆大于等于大根堆,在插入新元素的时候,如果两个堆一样大,则插入小根堆,否则插入大根堆。
- 为了保证数据在合适的位置,若插入大根堆,则先将其插入到小根堆,然后再将小根堆的堆顶元素放到大根堆里,反之也是。
代码
class MedianFinder {
// 使用大根堆和小根堆,堆顶是取中位数的地方
PriorityQueue<Integer> maxHeap;
PriorityQueue<Integer> minHeap;
/** initialize your data structure here. */
public MedianFinder() {
maxHeap = new PriorityQueue<Integer>((x, y) -> (y - x));
minHeap = new PriorityQueue<Integer>();
}
public void addNum(int num) {
if(maxHeap.size() != minHeap.size()){
// 加到max里
minHeap.add(num);
maxHeap.add(minHeap.poll());
}else{
// 加到min里
maxHeap.add(num);
minHeap.add(maxHeap.poll());
}
}
public double findMedian() {
if(maxHeap.size() != minHeap.size()){
return minHeap.peek();
}else{
return (maxHeap.peek() + minHeap.peek()) / 2.0;
}
}
}