数据流中的中位数(堆)

这篇博客探讨了如何在数据流中实时计算中位数。算法一使用STL中的vector,每次插入元素后保持有序,从而快速获取中位数。算法二则采用大根堆和小根堆,分别维护数据流中较小的一半和较大的一半,以确保堆顶元素为中位数。这两种方法都能够在数据流不断更新时有效计算中位数。
摘要由CSDN通过智能技术生成

如何得到一个数据流中的中位数?

如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。

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

样例
输入:1, 2, 3, 4

输出:1,1.5,2,2.5

解释:每当数据流读入一个数据,就进行一次判断并输出当前的中位数。

算法一:
用STL,维护一个有序的vector数组,每次插入一个数时,先用lower_bound找到第一个大于等于x的位置,然后插入;

class Solution {
public:
    vector<int> nums;
    void insert(int num){
        auto x = lower_bound(nums.begin(),nums.end(),num);
        nums.insert(x,num);
    }

    double getMedian(){
        int n = nums.size();
        if(n&1) return nums[n/2];
        return (nums[n/2] + nums[n/2-1]) / 2.0;
    }
};

算法二:
用一个大根堆来维护左半边较小的数,小根堆来维护右半边较大的数,那么两个堆的对顶就是一组有序数中间相邻的两个数;
在这里插入图片描述
C++代码:

class Solution {
public:
    priority_queue<int> max_q;
    priority_queue<int,vector<int>,greater<int>> min_q;
    void insert(int num){
        max_q.push(num);
        if(min_q.size() && min_q.top() < max_q.top()) {
            int minv = min_q.top(); min_q.pop();
            int maxv = max_q.top(); max_q.pop();
            min_q.push(maxv); max_q.push(minv);
        }
        if(max_q.size() - min_q.size() > 1){
            min_q.push(max_q.top());
            max_q.pop();
        }
    }

    double getMedian(){
        if((max_q.size()+min_q.size())&1) return max_q.top();
        return (max_q.top()+min_q.top()) / 2.0;
    }
};
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值