剑指 Offer -- 数据流中的中位数(六十三)

数据流中的中位数(六十三)

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

代码(已在牛客上 AC)

这道题听说有很多思路, 但是呢各种方法的时间或空间复杂度不同. 这里采用的是两个堆, 使用最大堆保存数据流中较小的数, 使用最小堆保存数据流中较大的数, 这样的话, (qmin.top() + qmax.top()) / 2. 就是中位数(偶数情况下);

而对于奇数情况, 在两个堆中的数据为偶数的情况下, 对于插入的元素, 总是向最小堆中插入; 即奇数情况下, qmin 中的元素总比 qmax 多一个.

// 1. 保证最小堆 qmin 中的元素都大于最大堆 qmax 中的元素
// 2. 对于插入新元素, 如果当前两个堆中的元素个数之和为偶数, 就将新元素插入到最小堆中;
// 否则插入到最大堆 qmax 中.
class Solution {
public:
    void Insert(int num) {
        if ((qmax.size() + qmin.size()) % 2) {
            qmin.push(num);
            qmax.push(qmin.top());
            qmin.pop();
        }
        else {
            qmax.push(num);
            qmin.push(qmax.top());
            qmax.pop();
        }
    }

    double GetMedian() {
        if (qmax.empty() && qmin.empty()) return 0.0;
        if ((qmax.size() + qmin.size()) % 2) return double(qmin.top());
        else return double((qmax.top() + qmin.top())) / 2.;
    }
private:
    priority_queue<int, vector<int>, less<int>> qmax; // 最大堆放小值
    priority_queue<int, vector<int>, greater<int>> qmin; // 最大堆放小值
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值