题目:如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数及时所有数值排序之后中间两个数的平均值。
解题思路:首先保证数据平均分配到两个堆中,因此两个堆中数据数目之差不能超过1.为了实现平均分配,可以在数据的总数是偶数时,把新数据插入最小堆,否则插入到最大堆。
还要保证最小堆中所有数字都大于最大堆中的数字。当插入最小堆时,先和最大堆中最大值比较,若插入的数比最大堆中的最大值大则直接插入到最小堆中;否则将最大堆中的最大值插入到最小堆,然后将该数插入最大堆中。
import java.util.Comparator;
import java.util.PriorityQueue;
public class Solution {
private int count = 0;
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer arg0, Integer arg1) {
return arg1.compareTo(arg0);
}
});
public void Insert(Integer num) {
count++;
if((count & 1) == 0) {//插入的是偶数个时,插入最小堆中
if(!maxHeap.isEmpty() && maxHeap.peek() > num) {
int temp = maxHeap.poll();
maxHeap.offer(num);
minHeap.offer(temp);
}else {
minHeap.offer(num);
}
}else {
//插入到最大堆中
if(!minHeap.isEmpty() && minHeap.peek() < num) {
int temp = minHeap.poll();
minHeap.offer(num);
maxHeap.offer(temp);
}else {
maxHeap.offer(num);
}
}
}
public Double GetMedian() {
if(count == 0)
throw new RuntimeException("no available number");
double result;
if((count & 1) == 1) {
result = maxHeap.peek();
return result;
}else {
result = (minHeap.peek()+maxHeap.peek())/2.0;
return result;
}
}
}