• LeetCode 295. Find Median from Data Stream(multiset,heap)


    题目

    题意:有n个操作,存入数字,和输出中位数

    题解:要确保输入数字的操作和输出中位数的操作,都是低于等于Log(n)的效率。
    那么怎么做呢?我们维护两个multiset ,内部是一棵红黑树。一个树A 维护的是较大值,树B维护的是较小值。A,B平分秋色。
    中位数显然就是A里的最小值和B里的最大值中选择。那么在存数字的时候判断这个数字应该放到哪个树里,然后再需要判断A,B的元素数量差,如果出现差值大于1,就要把较多的那个树的某个极值元素放到较小的那个树里,始终保持两个树的元素数量差不超过1,所以存入数字的效率是O(logn*3)
    而取中位数是O(1)的效率
    不知道为什么multiset的size()函数,会超时,难道是O(n)的效率取size吗?介绍里明明是constant的时间复杂度啊。
    用优先队列也可以的。效率是一样的。

    class MedianFinder {
    public:
        /** initialize your data structure here. */
        multiset<int> m1;
        multiset<int> m2;
        int n=0;
        int len1;
        int len2;
        MedianFinder() {
            m1.clear();
            m2.clear();
            len1=0;
            len2=0;
            
        }
        
        void addNum(int num) {
           
            if(len1==0&&len2==0)
            {
                m1.insert(num);
                len1++;
                n++;
                return;
            }
           
            multiset<int>::iterator it = prev(m1.end());
            if(num < *it)
            {
                m1.insert(num);
                len1++;
            }
            else
            {
                m2.insert(num);
                len2++;
            }
            
            if(len1<len2-1)
            {
                m1.insert(*m2.begin());
                len1++;
                m2.erase(m2.begin());
                len2--;
            }
            
            if(len1-1>len2)
            {
                m2.insert(*prev(m1.end()));
                len2++;
                m1.erase(prev(m1.end()));
                len1--;
            }
            
            n++;
        }
        
        double findMedian() {
            
            if(n&1)
            {
                if(len1<len2)
                    return *m2.begin();
                else
                    return *prev(m1.end());
            }
            else
                return 1.0*(*prev(m1.end())+*m2.begin())/2;
            
        }
    };
    
    /**
     * Your MedianFinder object will be instantiated and called as such:
     * MedianFinder* obj = new MedianFinder();
     * obj->addNum(num);
     * double param_2 = obj->findMedian();
     */
    
  • 相关阅读:
    vue 环境的搭建及初始化项目
    vue axios 发送post请求,后端接收参数为null
    iOS-WKWebView的使用
    iOS开发GCD(3)-数据安全
    iOS开发-本地存储(偏好设置,Plist,归档)
    ios开发GCD(2)-dispatch_semaphore_t信号量计数器
    ios开发多线程之NSThread
    Runtime消息动态解析与转发流程
    iOS动画-从UIView到Core Animation
    贝塞尔曲线UIBezierPath简单使用
  • 原文地址:https://www.cnblogs.com/dacc123/p/12427764.html
Copyright © 2020-2023  润新知