中间的那个数比排序后的左边的大,比右边的小。创建一个大顶堆和小顶堆。每次加数的时候,大顶堆加一次,小顶堆加一次。中位数就是堆顶的情况。画图举例走一次就会了。
class MedianFinder {
int count = 0;
PriorityQueue<Integer> minHeap = new PriorityQueue();
PriorityQueue<Integer> maxHeap = new PriorityQueue(new Comparator<Integer>(){
@Override
public int compare(Integer o1, Integer o2){
return o2-o1;
}
});
/** initialize your data structure here. */
public MedianFinder() {
}
public void addNum(int num) {
//大顶堆加一次,小顶堆加一次。如果之前是偶数次,这次就加入到小顶堆中
if((count & 1) == 0){
//因为小顶堆中要添加元素,这个元素可以是当前加入来的数,也可以是从大顶堆中来。
if(!maxHeap.isEmpty() && num < maxHeap.peek()){
int tem = maxHeap.poll();
maxHeap.add(num);
num = tem;
}
minHeap.add(num);
}else{//又来数据后,这次就加到大顶堆
//同样的,如果此时的数据比小顶堆中的堆顶元素还大,说明这个数是要加到小顶堆中的,那就把小堆堆顶元素加到大顶堆中来。
if(!minHeap.isEmpty() && num > minHeap.peek()){
int tem = minHeap.poll();
minHeap.add(num);
num = tem;
}
maxHeap.add(num);
}
count++;
}
public double findMedian() {
int allCount = minHeap.size() + maxHeap.size();
if((allCount & 1) == 1){
return (double)minHeap.peek();
}else{
return (minHeap.peek() + maxHeap.peek())/2.0;
}
}
}
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/