剑指offer——数据流中的中位数

本文介绍了一种高效计算数据流中位数的方法,利用最大堆和最小堆动态维护数据流的中位数,适用于实时数据处理场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。

思路:

/***
    对于一个升序排序的数组,中位数为左半部分的最大值,右半部分的最小值,而左右两部分可以是无需的,只要保证左半部分的数均小于
    右半部分即可。因此,左右两半部分分别可用最大堆、最小堆实现。
    首先定义:如果有奇数个数,则中位数放在左半部分;如果有偶数个数,则取左半部分的最大值、右边部分的最小值之平均值
    分两种情况讨论:
    当目前有偶数个数字时,数字先插入最小堆,然后选择最小堆的最小值插入最大堆(第一个数字插入左半部分的最小堆)
    当目前有奇数个数字时,数字先插入最大堆,然后选择最大堆的最大值插入最小堆
    注意最大堆最小堆都是针对array[0]来说的 min[0]是最小值,则min是递增排序;max[0]是最大值,故递减排序
    ***/

代码:

语言C++,已通过牛客网在线测试。

class Solution {
public:
    //说明:第一个数据插入左边的最大堆
    //目前有偶数个数时,num先插入最小堆,然后选择最小堆的最小值插入最大堆
    //目前有奇数个数时,num先插入最大堆,然后选择最大堆的最大值插入最小堆
    void Insert(int num)
    {
        if(count % 2 == 0){
            min.push_back(num);
            push_heap(min.begin(), min.end(), greater<int>());
            max.push_back(min[0]);
            push_heap(max.begin(), max.end(), less<int>());
            pop_heap(min.begin(), min.end(), greater<int>());
            min.pop_back();
        }else{
            max.push_back(num);
            push_heap(max.begin(), max.end(), less<int>());
            min.push_back(max[0]);
            push_heap(min.begin(), min.end(), greater<int>());
            pop_heap(max.begin(), max.end(), less<int>());
            max.pop_back();
        }
        count ++;
    }

    double GetMedian()
    {
        if(count % 2 == 1) return (double)max[0];
        return (double)(max[0] + min[0]) / 2;
    
    }
private:
    int count = 0;
    vector<int> min;
    vector<int> max;
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值