class MedianFinder {
private PriorityQueue<Integer> small;
private PriorityQueue<Integer> large;
/** initialize your data structure here. */
public MedianFinder() {
//大顶堆:保存较小的一半
small = new PriorityQueue<>((a, b) -> Integer.compare(b, a));
//小顶堆:保存较大的一半
large = new PriorityQueue<>();
}
/**
为了保证large堆整体大于small堆,想要往 large 里添加元素,不能直接添加,而是要先往 small 里添加,然后再把 small 的堆顶元素加到 large 中;向 small 中添加元素同理。
为什么呢?
假设我们准备向 large 中插入元素:
如果插入的 num 小于 small 的堆顶元素,那么 num 就会留在 small 堆里,为了保证两个堆的元素数量之差不大于 1,作为交换,把 small 堆顶部的元素再插到 large 堆里。
如果插入的 num 大于 small 的堆顶元素,那么 num 就会成为 samll 的堆顶元素,最后还是会被插入 large 堆中。
反之,向 small 中插入元素是一个道理,这样就巧妙地保证了 large 堆整体大于 small 堆,且两个堆的元素之差不超过 1,那么中位数就可以通过两个堆的堆顶元素快速计算了。
*/
public void addNum(int num) {
if(small.size() >= large.size()){
small.offer(num);
large.offer(small.poll());
}else{
large.offer(num);
small.offer(large.poll());
}
}
/**
如果两个堆元素个数不等,元素个数多的堆的堆顶元素即为中位数;
如果相等,两个堆顶元素的平均数即为中位数
*/
public double findMedian() {
if(large.size() > small.size()){
return large.peek();
}else if(small.size() > large.size()){
return small.peek();
}else{
return (small.peek() + large.peek()) / 2.0;
}
}
}
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/
共以下 12 个回答
c++ 代码, less > maxHeap; , greater > minHeap;
class MedianFinder {
public:
// 最大堆,存储左边一半的数据,堆顶为最大值
priority_queue<int, vector
// 最小堆, 存储右边一半的数据,堆顶为最小值
priority_queue<int, vector
/** initialize your data structure here. */
MedianFinder() {
}
};
class MedianFinder {//优先队列 自动维护一个单调队列 queMin; queMax;
PriorityQueue
PriorityQueue
}
想不出来,看题解看懂了,用两个堆的栈顶元素控制中位数。难点在于在动态数组中添加元素要怎么添加。
8.1
Day23:下面是代码