• 剑指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)

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

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

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

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

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

    当插入元素

  • 相关阅读:
    div+css 遮罩层
    高可用开源方案Heartbeat vs Keepalived
    nginx+keepalive 实现高可用负载均衡方案
    KeepAlive详解
    (转)高可用可伸缩架构实用经验谈 ---- 重要
    OpenStack与KVM的区别与联系
    架构师于小波:魅族实时消息推送架构
    抛开flash,自己开发实现C++ RTMP直播流播放器
    (转)C++实现RTMP协议发送H.264编码及AAC编码的音视频,摄像头直播
    (转)OC学习笔记 @property的属性 strong 和 weak 理解
  • 原文地址:https://www.cnblogs.com/SkyeAngel/p/9056387.html
Copyright © 2020-2023  润新知