Numbers are randomly generated and passed to a method. Write a program to find and maintain the median value as new values are generated.
随机产生一些数传递给一个函数,写程序找出并维护这些数的中位数。
Solution:
1 足够大的数组,将元素排序。 O(1) get median.
new number comes, insert into the array, O(N) time to move bigger element to the end.
2 Heap
(max or min) , O(logN) to insert
取中位数需要先排序,时间复杂度O(nlogn)
3 基于方法2, 用两个heap,一个maxheap,value <= median,一个minheap , value > medina.
这样,maxheap.size() > minHeap.size(), maxHeap.top()就是median
如果两个heap大小一样,median就是两个heap的top的平均数
public class MinHeapComparator implements Comparator<Integer>{
//comparator sort integers from lowest to highest
public int compare(Integer o1, Integer o2){
if(o1 > o2) return 1;
else if( o1 == o2) return 0;
else return -1;
}
}
public class MaxHeapComparator implements Comparator<Integer>{
// Comparator that sorts integers from highest to lowest
@Override
public int compare(Integer o1, Integer o2){
if(o1 < o2) return 1;
else if( o1 == o2) return 0;
else return -1;
}
}
public static double getMedian() {
/* maxHeap is always at least as big as minHeap. So if maxHeap is empty, then minHeap is also. */
if (maxHeap.isEmpty()) return 0;
if (maxHeap.size() == minHeap.size()) {
return ((double)minHeap.peek() + (double) maxHeap.peek()) / 2;
} else {
/* If maxHeap and minHeap are of different sizes, then maxHeap must have one extra element. Return maxHeap¡¯s top element.*/
return maxHeap.peek();
}
}
插入一个新数:
注意需要判断应该插入maxHeap还是minHeap,然后根据size,banalance两个heap确保maxheap至多比minheap多一个元素
//insert a new number
public void addNewNumber(int randomNum){
//
if(maxHeap.size() == minHeap.size()){
//should add to max heap to make sure maxheap is bigger
if((minHeap.peek() != null) && (randomNum > minHeap.peek())){
//> median, should add to min heap, to make sure maxheap has more number
//need remove one to maxheap
//O(logN)
maxHeap.offer(minHeap.poll()); //move top to maxHeap
minHeap.offer(randomNum);
}else{
//<= median
maxHeap.offer(randomNum);
}
}else{
//maxHeap has more number
if(randomNum < maxHeap.peek()){
//move one to min to balance the two heap
minHeap.offer(maxHeap.poll());
maxHeap.offer(randomNum);
}else{
minHeap.offer(randomNum);
}
}
}