• 295. 数据流的中位数


    中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。

    例如,

    [2,3,4] 的中位数是 3

    [2,3] 的中位数是 (2 + 3) / 2 = 2.5

    设计一个支持以下两种操作的数据结构:

    void addNum(int num) - 从数据流中添加一个整数到数据结构中。
    double findMedian() - 返回目前所有元素的中位数。
    示例:

    addNum(1)
    addNum(2)
    findMedian() -> 1.5
    addNum(3)
    findMedian() -> 2
    进阶:

    如果数据流中所有整数都在 0 到 100 范围内,你将如何优化你的算法?
    如果数据流中 99% 的整数都在 0 到 100 范围内,你将如何优化你的算法?

    链接:https://leetcode-cn.com/problems/find-median-from-data-stream
    思路都放在代码里了。结合代码看味道更好

    class MedianFinder {
    
        //基本思想 建立两个堆 分别存放一半的数据
        //1.保证大根堆的堆顶永远小于小根堆顶
        //2.保证两个堆的数据差只为1
        public PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>(); //小顶堆,默认容量为11
        public PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(11,new Comparator<Integer>  (){ //大顶堆,容量11
            @Override
            public int compare(Integer i1,Integer i2){
                return i2-i1;
            }
        });
    
        /** initialize your data structure here. */
        public MedianFinder() {
            
        }
        
       public void addNum(int num) {
    
            if(maxHeap.isEmpty())//如果大根堆为空 则把数字放入大根堆
            {
                maxHeap.offer(num);
                return;
            }
            //如果两个堆的大小一样
            //第一中情况 两个堆的数量一样 保证大根堆的头 比小根堆的头要小 且相差为1
            if(maxHeap.size()==minHeap.size())
            {
                //比小根堆头大 放小根堆;比小根堆头小 放大根堆 (这边其实也能和大根堆比都能过)
                if(num>minHeap.peek())
                {
                    minHeap.offer(num);
                }
                else
                {
                    maxHeap.offer(num);
                }
            }
            else if(minHeap.size()>maxHeap.size())
            {//如果小根堆多一些,那就和小根堆的数字比 这时候可以在笔记本上画一下
            //例子为6 10 11 12/7
                if(num>minHeap.peek())//12>10 需要把10弹出到大根
                {
                    maxHeap.offer(minHeap.poll());
                    minHeap.offer(num);
                }
                else//7<10 直接去大根  我就是这边的代码写错了 调了很久
                {
                    maxHeap.offer(num);
                }
            }
            else if(minHeap.size()<maxHeap.size())
            {//如果大根堆多一些 直接和大根堆比 实例 4,3/10
                if(num>maxHeap.peek())
                {
                    minHeap.offer(num);//10大于4 直接去小根那边
                }
                else//3《4 要先把4送到小根 然后把三放进去
                {
                    minHeap.offer(maxHeap.poll());
                    maxHeap.offer(num);
                }
            }
    
        }
        
        public double findMedian() {
            double temp;
            if(maxHeap.size()==minHeap.size())
            {
                return (maxHeap.peek()+minHeap.peek())/2.0;//记得这边转一下啊float
            }
            else if(maxHeap.size()>minHeap.size())
            {
                return maxHeap.peek();
            }
            else
            {
                return minHeap.peek();
            }
    
    
            }
        
    }
    
    /**
     * Your MedianFinder object will be instantiated and called as such:
     * MedianFinder obj = new MedianFinder();
     * obj.addNum(num);
     * double param_2 = obj.findMedian();
     */
  • 相关阅读:
    PHP反射
    Ramda函数式编程之PHP
    双因素算法存疑
    百度编辑器复制微信图片无法保存
    go语言可变参数的坑
    xorm的sql builder
    vue前后分离动态路由和权限管理方案
    分布式唯一id生成器的想法
    Java IO 之 InputStream源码
    图解 & 深入浅出Java初始化与清理:构造器必知必会
  • 原文地址:https://www.cnblogs.com/William-xh/p/13838537.html
Copyright © 2020-2023  润新知