栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

力扣295.数据流的中位数[困难]

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

力扣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

解法一:堆实现(B大顶堆和S小顶堆分别存放小数、大数)

        分析:使用优先队列保持有序结构,设元素总数为 N = m + n ,其中 m 和 n 分别为 S和 B 中的元素个数。

class MedianFinder {
public:
    priority_queue,greater> S;//小顶堆
    priority_queue,less> B;//大顶堆
    MedianFinder() {}
    
    void addNum(int num) {
        if(S.size()!=B.size()){//左边大数多了
            S.push(num);
            B.push(S.top());
            S.pop();
        }
        else{
            B.push(num);
            S.push(B.top());
            B.pop();            
        }
    }
    
    double findMedian() {
        return S.size()!=B.size()? S.top(): (S.top()+B.top())/2.0;
    }
};

解法二:有序队列+双指针

        我们把有序集合看作自动排序的数组,使用双指针指向有序集合中的中位数元素即可。当累计添加的数的数量为奇数时,双指针指向同一个元素。当累计添加的数的数量为偶数时,双指针分别指向构成中位数的两个数。

class MedianFinder {
public:
    MedianFinder() {left=nums.begin();right=nums.end();}
    void addNum(int num) {
        int len = nums.size();
        nums.insert(num);
        if(len<1){//数据为空
            left=right=nums.begin();
        }
        else if(len&1){//数据为奇数
            if(num<*left){
                left--;
            }
            else{
                right++;
            }
        }
        else{//数据为偶数,新添加的数字有三种情况,夹在原来偶数中间,分在左或者右
            // if(num<=*left){
            //     right--;
            //     //left=right;//这一步是针对,新插入值等于左侧的值,这时候这个值会插入到两个值的中间,set的重复值插入到原来数值的右边
                                //可以使用 num<*left 在判断的时候将其归类为第三类中间值去处理
            // }
            if(num<*left){
                right--;
            }            
            else if(num>=*right){
                left++;
            }
            else{
                left++;right--;
            }
        }
    }
    
    double findMedian() {
        return (*left+*right)/2.0;
    }
private:
    multiset nums;
    multiset ::iterator left ,right;
};

解法三:存储时保持有序(超时)

class MedianFinder {
public:
    
    MedianFinder() {
    }
    
    void addNum(int num) {
        int i=0;
        //while (i=num){
                break;
            }
        }
        res.insert(res.begin()+i, num);
    }
    
    double findMedian() {
        if (res.empty()) return NULL;
        if (res.size() % 2) return res[res.size()/2];
        return (res[res.size()/2] + res[res.size()/2 -1] )/2.0;
        
    }
private:
    vector res;
};

解法四:私调用快速排序(超时)

class MedianFinder {
public:
    
    vector res;
    MedianFinder() {}//默认构造
    
    void addNum(int num) {
         res.push_back(num);
    }

    double findMedian() {
        int len = res.size();
        if(len<1){
            return 0;
        }
        //sort(res.begin(),res.end());这个时间会超时
        quicksort(res,0,len-1);
        if(len%2==0){
            return (res[len/2]+res[len/2-1])/2;
        }
        else{
            return res[(len-1)/2];
        }
    }
private:
    void quicksort(vector &arr,int l,int r){
        if(l>r)return;
        int i=l,j=r;
        while(i=arr[l])j--;
            while(i 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1003927.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号