[英]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.