剑指offer——数据流中的中位数

数据流中的中位数

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。

自己的想法是利用二叉搜索树,将插入进来的数据流放入一个TreeSet中,这样就是一个有顺序的树,所以在需要中位数时,直接找出它的中间位置的一个(或两个)值即可

其中涉及到了利用迭代器遍历Set

还有强制类型转换,int转成double最好是基本数据类型,而不用其包装类

import java.util.TreeSet;
import java.util.Iterator;
public class Solution {
    TreeSet<Integer> numbers = new TreeSet<>();
    public void Insert(Integer num) {
        numbers.add(num);
    }
    public Double GetMedian() {
        if(numbers.size() % 2 != 0){
            int index = 0;
            for(Integer num : numbers){
                if(index++ == (int)(numbers.size()/2)) return (double)num;
            }
        }else{
            int index = 0;
            Iterator<Integer> iterator = numbers.iterator();
            while(iterator.hasNext()){
                if(index++ == (int)(numbers.size()/2 - 1)){
                    Double sum  = (double)(iterator.next() + iterator.next());
                    return sum / 2;
                }
                iterator.next();
            }
        }
        return 0.0;
    }
}

  

看到其他人的做法:利用的是堆,一个大根堆(maxHeap),一个小根堆(minHeap)

然后大根堆中放的是数据中较小的一半,小根堆中放的是数据中较大的一半。

当插入元素时,如果是第奇数个,应该插在大根堆中,但是要先插入到小根堆中,然后把小根堆堆顶的元素弹出放到大根堆中。

如果是第偶数个,那么应该插在小根堆中,但是要先插入到大根堆中,把大根堆堆顶的元素弹出放到小根堆中。

当要输出中位数时,如果是偶数个,就在大根堆和小根堆中各取出堆定的那一个即可,

如果是奇数个,就直接取出大根堆的堆定即可。

当插入元素

原文地址:https://www.cnblogs.com/SkyeAngel/p/9056387.html