【题目描述】
【思路】
大根堆(maxHeap):存放较小的一半数字
小根堆(minHeap):存放较大的一半数字
如果数字个数为奇数个,那么大根堆存放的数字数量个数比小根堆多一
根据大小根堆的特点:
- 如果为奇数 那么中位数就是大根堆堆顶元素
- 如果是偶数 那么中位数就是大小根堆堆顶元素之和的一半
/**
大根堆(maxHeap):存放较小的一半数字
小根堆(minHeap):存放较大的一半数字
如果数字个数为奇数个,那么大根堆存放的数字数量个数比小根堆多一
根据大小根堆的特点:
1. 如果为奇数 那么中位数就是大根堆堆顶元素
2. 如果是偶数 那么中位数就是大小根堆堆顶元素之和的一半
* */
class Solution {
Queue<Integer> minHeap = new PriorityQueue<>(); //小根堆
/** lambda写法
Queue<Integer> maxHeap = new PriorityQueue<>(
(x, y)->( y - x)
); //大根堆
*/
Queue<Integer> maxHeap = new PriorityQueue<>(
new Comparator<Integer>(){
public int compare(Integer x, Integer y){
return y - x;
}
}
); //大根堆
public void insert(Integer num) {
//先往大根堆加入该元素
maxHeap.add(num);
//维护有序性:即大根堆总是存放较小的一半数字
//如果大根堆的堆顶元素大于小根堆的堆顶元素 则交换
//小根堆可能为null
if( !minHeap.isEmpty() && maxHeap.peek() > minHeap.peek() ){
int a = maxHeap.poll(), b = minHeap.poll();
maxHeap.add(b);
minHeap.add(a);
}
//如果大根堆的元素比一半加一还多的话 将大根堆的堆顶弹出插入小根堆
if( maxHeap.size() > minHeap.size() + 1 )
minHeap.add( maxHeap.poll() );
}
public Double getMedian() {
int count = minHeap.size() + maxHeap.size();
if( (count & 1) == 1){
return (double) maxHeap.peek();
} //奇数个
else return (minHeap.peek() + maxHeap.peek()) / 2.0;
}
}