查找随机生成的数字的中位数

时间:2014-08-13 07:43:05

标签: java algorithm median

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

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

这是否违反了寻找中位数的属性?

我使用max heap / min堆方法来解决问题。给出的解决方案如下:

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();
        }
    }

3 个答案:

答案 0 :(得分:1)

该方法的缺点是,当两个堆都为空时,它不起作用。

要修复,需要更改方法签名以返回Double(大写&#39; D&#39;)另外,当两个堆都为空时,需要添加一个检查以返回null。目前,将抛出尝试将null转换为double的异常。

当两个堆具有相同的大小时,另一个缺点是整数除法。你需要一个强制转换才能使它成为双重 - 所有这一切,这就是制作一个方法,找到一个整数的中位数,从而首先返回一个双倍。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

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