返回

极简攻略:精通 LeetCode 面试题 17.20 —— 连续中值

前端

算法题解:

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 是数字的个数。

希望这篇题解对您有所帮助。如果您有任何问题,请随时留言。