zoukankan      html  css  js  c++  java
  • 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();
     */
  • 相关阅读:
    分享诗集中国原创诗歌创作分享中心,欢迎博客园喜欢诗词的加入【诗词在线】
    转让上海水族馆票【吐血转让】08年10月有效【100¥】
    winform 里Control.Margin 属性到底是干嘛的?
    亚交联盟注册指南
    sqlserver 替换回车换行
    如何配置 imail 中域名的MX记录
    张良、萧何与韩信:汉初三杰悲情录[转]
    FBD内存全局缓冲内存 比dd2 ecc还要好啊。服务器内存和普通PC内存的区别[转载]
    脆弱的ASP.NET AJAX
    无法连接到服务器。 帐户: 'mail.bb.cn', 服务器: '*******', 协议: SMTP, 端口: 25, 安全(SSL): 否, 套接字错误: 10061, 错误号: 0x800CCC0E
  • 原文地址:https://www.cnblogs.com/William-xh/p/13838537.html
Copyright © 2011-2022 走看看