返回
极简攻略:精通 LeetCode 面试题 17.20 —— 连续中值
前端
2023-11-13 02:38:18
算法题解:
LeetCode 面试题 17.20 —— 连续中值,要求我们设计一个方法,能够在每次产生新值时,寻找当前所有值的中间值(中位数)并保存。
中位数是将一组数字从小到大排序后,位于中间位置的数。如果数字个数为偶数,则中位数是两个中间数的平均值。
解题思路:
为了高效地找到中位数,我们可以使用最小堆和最大堆两种数据结构。最小堆存储较小的半部分数字,最大堆存储较大的半部分数字。当产生新值时,我们将新值添加到较小的一堆中。如果较小的一堆中的数字个数比较大的一堆多,则将最小堆中的最大值弹出并添加到较大的一堆中。这样,两堆中的数字个数始终保持平衡。
当我们需要找到中位数时,我们可以直接比较两堆中的最大值和最小值。如果两堆中的最大值和最小值相等,则中位数就是这两个值。如果两堆中的最大值和最小值不相等,则中位数是两堆中的较大值和最小值的平均值。
代码示例:
import java.util.PriorityQueue;
class MedianFinder {
private PriorityQueue<Integer> maxHeap; // 最大堆,存储较小的一半数字
private PriorityQueue<Integer> minHeap; // 最小堆,存储较大的一半数字
public MedianFinder() {
maxHeap = new PriorityQueue<>((a, b) -> b - a); // 最大堆,使用 Comparator 逆序排序
minHeap = new PriorityQueue<>(); // 最小堆,使用默认排序
}
public void addNum(int num) {
maxHeap.add(num);
minHeap.add(maxHeap.poll()); // 将最大堆中的最大值弹出并添加到最小堆中
if (minHeap.size() > maxHeap.size()) { // 保持两堆中的数字个数平衡
maxHeap.add(minHeap.poll());
}
}
public double findMedian() {
if (maxHeap.size() == minHeap.size()) { // 两堆中的数字个数相等
return (maxHeap.peek() + minHeap.peek()) / 2.0; // 中位数是两堆中的较大值和最小值的平均值
} else { // 两堆中的数字个数不相等
return maxHeap.peek(); // 中位数是较大的一堆中的最大值
}
}
}
总结:
通过最小堆和最大堆这两种数据结构,我们可以高效地找到一组数字的中位数。这种方法的时间复杂度是 O(log n),其中 n 是数字的个数。
希望这篇题解对您有所帮助。如果您有任何问题,请随时留言。