• 数据流中的中位数 --剑指offer


    题目描述

    如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
     
    思路:最直接的思路不必多说
    链接:https://www.nowcoder.com/questionTerminal/9be0172896bd43948f8a32fb954e1be1
    来源:牛客网
    • 先用java集合PriorityQueue来设置一个小顶堆和大顶堆
    • 主要的思想是:因为要求的是中位数,那么这两个堆,大顶堆用来存较小的数,从大到小排列
    • 小顶堆存较大的数,从小到大的顺序排序*,显然中位数就是大顶堆的根节点与小顶堆的根节点和的平均数。
    • ⭐保证:小顶堆中的元素都大于等于大顶堆中的元素,所以每次塞值,并不是直接塞进去,而是从另一个堆中poll出一个最大(最小)的塞值
    • ⭐当数目为偶数的时候,将这个值插入大顶堆中,再将大顶堆中根节点(即最大值)插入到小顶堆中;
    • ⭐当数目为奇数的时候,将这个值插入小顶堆中,再讲小顶堆中根节点(即最小值)插入到大顶堆中;
    • ⭐取中位数的时候,如果当前个数为偶数,显然是取小顶堆和大顶堆根结点的平均值;如果当前个数为奇数,显然是取小顶堆的根节点

    我的代码

    import java.util.*;
    public class Solution {
        PriorityQueue<Integer> min=new PriorityQueue<>();
        PriorityQueue<Integer> max=new PriorityQueue<>(new Comparator<Integer>() {
                @Override
            public int compare(Integer o1, Integer o2) {
                return o2.compareTo(o1);
            }
        });
        int count=0;
        public void Insert(Integer num) {
            count++;
            if(count % 2 != 0){ //奇数
                max.offer(num);
                min.offer(max.poll());
            }else {
                min.offer(num);
                max.offer(min.poll());
            }
        }
    
        public Double GetMedian() {
            if(count % 2 != 0){
                return 1.0*min.peek();
            }else {
                return (min.peek() + max.peek())/2.0;
            }
        }
    
    }
  • 相关阅读:
    oracle数据库的乱码问题解决方案
    @HTML.checkboxFor()用法
    存储过程实现登录(.net)
    .net中大数据的处理
    xml总结
    获取指定日期是当前月的第几周
    JS中正则方法的使用
    获取指定日期的前一天日期
    通过Oracle函数实现.NET String.Format函数的简单版
    ReportViewer实现多语言
  • 原文地址:https://www.cnblogs.com/nlw-blog/p/12482784.html
Copyright © 2020-2023  润新知