题目描述:
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

思路:
利用PriorityQueue分别建立大顶堆和小顶堆,由于大顶堆是从大到小顺序排列的,小顶堆是从小到大排列的,将数据流的数分成两部分,较大的一部分放在小顶堆,较小的一部分放在大顶堆,所以大顶堆的根结点的值与小顶堆根结点的值,在数据流中应该是中间相邻的两个数。
规则:从count=0开始,对数据流num划分,每次划分到minHeap或者maxHeap中,
若count为偶数,将num分到大顶堆中(maxHeap.offer(num)),再把大顶堆中最大的值poll()出,放到小顶堆minHeap中;
若count为奇数,将num分到小顶堆中(minHeap.offer(num)),再把小顶堆中最小的值poll()出,放到大顶堆maxHeap中;
对count++;
最后一句count的值判定中位数取值。
只需对数据流中数据个数进行统计,若为偶,则中位数为大顶堆root值与小顶堆root值的平均值;若为奇,则中位数为小顶堆root值。

实现中的问题:
1、大顶堆的建立规则
2、最后输出的值类型为double,需要new Double()。

代码实现:

import java.util.PriorityQueue;
import java.util.Comparator;
public class Solution {

    //利用PriorityQueue建立大小顶堆
    //小顶堆
    private PriorityQueue<Integer> minHeap=new PriorityQueue<Integer>();
    //大顶堆
    private PriorityQueue<Integer> maxHeap=new PriorityQueue<Integer>(15,new Comparator<Integer>(){

        @Override
        public int compare(Integer o1,Integer o2){
            return o2-o1;
        }
    });
    int count=0;   //用来记录当前的奇偶
    public void Insert(Integer num) {
        if(count%2==0){
            maxHeap.offer(num);
            int max=maxHeap.poll();
            minHeap.offer(max);
        }else{
            minHeap.offer(num);
            int min=minHeap.poll();
            maxHeap.offer(min);
        }
        count++;
    }

    public Double GetMedian() {
        if(count%2==0){
            return new Double(minHeap.peek()+maxHeap.peek())/2;
        }else{
            return new Double(minHeap.peek());
        }
    }
}