. 利用自定义比较器 Comparator 实现类完成上一题。
时间: 2023-06-26 15:04:22 浏览: 92
Comparator比较使用
好的,下面是使用自定义比较器实现上一题的代码:
```java
import java.util.Comparator;
import java.util.PriorityQueue;
public 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) {
if (maxHeap.isEmpty() || num <= maxHeap.peek()) {
maxHeap.offer(num);
if (maxHeap.size() > minHeap.size() + 1) {
minHeap.offer(maxHeap.poll());
}
} else {
minHeap.offer(num);
if (minHeap.size() > maxHeap.size()) {
maxHeap.offer(minHeap.poll());
}
}
}
public double findMedian() {
if (maxHeap.size() == minHeap.size()) {
return (maxHeap.peek() + minHeap.peek()) / 2.0;
} else {
return maxHeap.peek();
}
}
}
```
这里我们使用了一个大根堆和一个小根堆来维护数据流中的数字。其中,大根堆中存放的是小于等于中位数的数字,小根堆中存放的是大于等于中位数的数字。
当我们向数据流中添加数字时,我们首先将其加入到大根堆中。如果大根堆中的数字比小根堆中的数字多了 2 个,我们就将大根堆中的最大值(也就是中位数)弹出并加入到小根堆中。如果新加入的数字比大根堆中的最大值(也就是中位数)要大,那么我们就将其加入到小根堆中。此时如果小根堆中的数字比大根堆中的数字多了 1 个,我们就将小根堆中的最小值弹出并加入到大根堆中,以保证大根堆中的数字比小根堆中的数字多不超过 1 个。
最后,我们可以利用大根堆和小根堆中的数字计算出中位数。如果大根堆和小根堆中的数字个数相等,那么中位数就是它们的堆顶数字之和除以 2;否则中位数就是大根堆的堆顶数字。
阅读全文