描述:如果数据流中读出奇数个值,那么中位数就是数值排序之后位于中间的数值,如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后的中间两个数的平均值。
方法一:排好序判断个数,然后得出中位数,这里代码就不写啦。
方法二:构建一个大顶堆和一个小顶堆,把数据流中的数据分别放到这俩个堆中,保证大顶堆的数据都小于小顶堆的数据,这样不用排序也能获取到中位数。代码如下:
// 优先队列默认是小顶堆
staticPriorityQueue<Integer> minHeap = new PriorityQueue();
// 重写比较器让他变成大顶堆
staticPriorityQueue<Integer> maxHeap = new PriorityQueue((o1,o2)->(Integer)o2 - (Integer)o1);
// 用于计数,让俩个堆插入数据时持平
staticint count = 0;
public static void add(Integer number) {
if (count % 2 == 0) {
// 为了使小顶堆里的数据都比大顶堆的数据大 每次插入都要进行操作
minHeap.add(number);
// 加入的元素为基数时大顶堆 要多一个元素 根就是中位数了
maxHeap.add(minHeap.poll());
} else {
maxHeap.add(number);
minHeap.add(maxHeap.poll());
}
count ++;
}
public static double getMedian() {
if (count % 2 == 0) {
return (minHeap.peek() +maxHeap.peek()) / 2.0;
} else {
// 为计数时大顶堆的根就是中位数 因为大顶堆多一个元素
return (double)maxHeap.peek();
}
}
public static void main(String[] args) {
add(1);
add(2);
System.out.println(getMedian()); // 1.5
add(3);
System.out.println(getMedian()); // 2.0
}
总结:利用几何的特点,有时候可以很快找到答案。