繁体   English   中英

查找随机数的中位数

[英]Find median of randomly generated numbers

Qn(摘自第91页的破解编码采访),数字是随机生成的,并传递给方法。 编写程序以在生成新值时查找并维护中间值。

我的问题是:如果maxHeap为空,为什么可以在下面的getMedian()方法中返回minHeap.peek(),反之亦然呢?

这不违反求中位数的属性吗?

我正在使用最大堆/最小堆方法来解决此问题。 给出的解决方案如下:

private static Comparator<Integer> maxHeapComparator, minHeapComparator;
    private static PriorityQueue<Integer> maxHeap, minHeap;

    public static void addNewNumber(int randomNumber) {
        if (maxHeap.size() == minHeap.size()) {
            if ((minHeap.peek() != null)
                    && randomNumber > minHeap.peek()) {
                maxHeap.offer(minHeap.poll());
                minHeap.offer(randomNumber);
            } else {
                maxHeap.offer(randomNumber);
            }
        } else {
            if (randomNumber < maxHeap.peek()) {
                minHeap.offer(maxHeap.poll());
                maxHeap.offer(randomNumber);
            } else {
                minHeap.offer(randomNumber);
            }
        }
    }

    public static double getMedian() {
        if (maxHeap.isEmpty()) {
            return minHeap.peek();
        } else if (minHeap.isEmpty()) {
            return maxHeap.peek();
        }
        if (maxHeap.size() == minHeap.size()) {
            return (minHeap.peek() + maxHeap.peek()) / 2;
        } else if (maxHeap.size() > minHeap.size()) {
            return maxHeap.peek();
        } else {
            return minHeap.peek();
        }
    }

该方法有一个缺点,即在两个堆都是空的情况下它不起作用。

要解决此问题,需要将方法签名更改为返回Double(大写字母为“ D”),并且当两个堆都为空时,还需要添加检查以返回null。 当前,将尝试将null转换为double的尝试失败将引发异常。

另一个缺点是两个堆的大小相同时的整数除法。 您需要进行强制转换以使其倍增-毕竟,这是使找到整数中位数的方法首先返回双精度的方法的全部要点。

这种方法的另一个缺点是它不能很好地扩展,例如无法适应内存中的堆大小。

一个非常好的近似算法只是简单地存储一个固定的增量(例如0.10)的近似中位数,该增量选择为适合问题的规模。 对于每个值,如果该值较高,则添加0.10。 如果该值较低,则减去0.10。 结果近似于中位数,可以很好地缩放,并且可以存储为4或8个字节。

只是这样做...否则一切正确:

return new Double(minHeap.peek() + maxHeap.peek()) / 2.0;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM