簡體   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