JZ63-数据流中的中位数

【题目描述】

如何得到一个数据流中的中位数
如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。
如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

【解法】
1.暴力解法

class Solution {
public:
    #define SCD static_cast<double>//C++强制类型转换操作符 static_cast
    //参考连接:https://blog.csdn.net/wangkai_123456/article/details/75066384
    vector<int> v;
    void Insert(int num)
    {
        v.push_back(num);
    }

    double GetMedian()
    { 
        sort(v.begin(), v.end());
        int sz=v.size();
        if(sz&1) return SCD(v[sz>>1]);
        else
            return SCD(v[sz>>1]+v[(sz-1)>>1])/2;
    }

};

2.插入排序

class Solution {
public:
    #define SCD static_cast<double>
    vector<int> v;
    void Insert(int num)
    {
        if (v.empty()) {
            v.push_back(num);
        }
        else {
            auto it = lower_bound(v.begin(), v.end(), num);
            //lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字
            //找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
            v.insert(it, num);//在it处插入num
        }
    }

    double GetMedian()
    { 
        int sz = v.size();
        if (sz & 1) {
            return SCD(v[sz >> 1]);
        }
        else {
            return SCD(v[sz >> 1] + v[(sz - 1) >> 1]) / 2;
        }
    }

};

3.堆(优先队列priority_queue:https://www.cnblogs.com/huashanqingzhu/p/11040390.html

class Solution {
public:
    
    //例子
    //输入:1, 2, 3, 4
    //输出:1,1.5,2,2.5
    
    //大小根堆
    //小根堆 较大的数字 最小的是根节点(top)
    //大根堆 较小的数字 最大的是根节点(top)
    //大根堆 - 小根堆 = 1/0
    
    priority_queue<int> maxheap;
    priority_queue<int, vector<int>, greater<int>> minheap;
    
    void Insert(int num)
    {
        //都无脑先插入 大根堆
        maxheap.push(num);
        
        //******************************************************//
        //大根堆 - 小根堆 = 1/0
        if(maxheap.size() - minheap.size() > 1)
        {
            //从大根堆中拿最大的元素到小根堆
            minheap.push(maxheap.top());
            maxheap.pop();
        }
        
        //*************************************************************//
        //插入的元素较大
        //大根堆的根  > 小根堆的根 
        //交换
        while(minheap.size() && maxheap.top() > minheap.top())
        {
            int max = maxheap.top(), min = minheap.top();
            maxheap.pop(), minheap.pop();
            maxheap.push(min), minheap.push(max);
        }
        //*****************这俩步骤可以交换,因为是数据流*********//
    }

    double GetMedian()
    { 
        //奇数
        if((maxheap.size() + minheap.size()) % 2 == 1) return maxheap.top();
        //偶数
        return (maxheap.top() + minheap.top()) /2.0;
    }

};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值