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