42.数据流中的中位数
如何得到一个数据流中的中位数?
如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。
如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
数据范围:
数据流中读入的数据总数 [1,1000]。
样例:
输入:1, 2, 3, 4
输出:1,1.5,2,2.5
解释:每当数据流读入一个数据,就进行一次判断并输出当前的中位数。
代码:
class Solution {
//小顶堆,存储较大的一半数字(堆顶是较大数中的最小值)
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
//大顶堆,存储较小的一半数字(堆顶是较小数中的最大值)
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
public void insert(Integer num) {
//如果小顶堆为空,或者数字大于小顶堆的最小值(即属于较大的一半),将该数字放入较大的一半
if(minHeap.isEmpty()||num>minHeap.peek())minHeap.offer(num);
//否则放入较小的一半
else maxHeap.offer(num);
//平衡两个堆的大小,确保它们的大小差不超过1
//如果较大的一半比较小的一半多2个元素,将较大的一半的最小值移到较小的一半
if(minHeap.size()>maxHeap.size()+1)maxHeap.offer(minHeap.poll());
//如果较小的一半比较大的一半多,将较小的一半的最大值移到较大的一半
else if(maxHeap.size()>minHeap.size())minHeap.offer(maxHeap.poll());
}
public Double getMedian() {
//如果两堆大小相等,中位数是两堆顶的平均值
if(minHeap.size() == maxHeap.size())return (minHeap.peek()+maxHeap.peek())/2.0;
//否则中位数在较大一半的堆顶(因为较大一半可能多1个元素)
else return minHeap.peek()*1.0;
}
}

浙公网安备 33010602011771号