数据流中的中位数

406 篇文章 0 订阅
159 篇文章 2 订阅

1,题目要求

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

2,题目思路

对于这道题,要去在时刻插入数据的同时,返回当前数组中的中位数。

在计算中位数时,有两种情况,一种是数组长度为奇数时,返回当前数组的中间值——nums[nums.size()/2]即可。
当数组长度为偶数时,则是靠近中间对称的两个数字的平均值。

因此,如果我们在构建数组的过程中,能够时刻对当期数组的中间元素进行记录,就可以时刻获得当前数组的中位数了。

事实上,如果我们在构建数组时,将数组一分为二,使得left中的数组值都比right中的数组值要小,而且可以从left中取到其中最大的,而且可以从right中取到其最小的,这样,就可以分轻松的实现这个问题了。

在解决上,我们使用优先队列——priority_queue,即一种堆结构,其中:

  • priority_queue<int, vector, less> left,构建一个大顶堆
  • priority_queue<int, vector, greater> right,构建一个小顶堆

left中,top元素即为当前左半部分最大的;
right中,top元素即为当前右半部分最小的;

于是,进行Insert时;除了要保证左半部分的值都比右半部分的值小之外,还需要保持,左边大顶堆的大小最多只能比右边小顶堆的大小大1(由于奇数次的插入)

又因为最后返回的,要么是左侧的top、要么是左侧top与右侧top的平均值,因此,右侧的小顶堆的大小不能比左边的大顶堆的大小要大。

3,代码实现

class Solution {
public:
    void Insert(int num)
    {
        if(left.empty() || num <=left.top())
            left.push(num);
        else
            right.push(num);
        if(left.size() > right.size()+1){
            right.push(left.top());
            left.pop();
        }
        if(left.size() < right.size()){
            left.push(right.top());
            right.pop();
        }
        return;
    }

    double GetMedian()
    { 
        if(left.size() == right.size())
            return (left.top()+right.top())/2.0;
        else
            return left.top();
    }
private:
    priority_queue<int, vector<int>, less<int>> left;
    priority_queue<int, vector<int>, greater<int>> right;

};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值