剑指 Offer-41.数据流中的中位数c++

---------------------------------二刷2021/1/25-------------------------------
无论我们要放到左边还是右边,都不是直接放num,而是从左/右中拿出那个在规定规则下面一定属于另外一个堆的数字,所以是正确的

class MedianFinder {
public:
    int flag = 0;
    priority_queue<int, vector<int>, less<int>> left;
    priority_queue<int, vector<int>, greater<int>> right;
    /** initialize your data structure here. */
    MedianFinder() {
        
    }

    void addNum(int num) {
        //flag初始为0,说明为0是偶数情况
        if(flag == 0) {
            left.push(num);
            right.push(left.top());
            left.pop();
        }
        else {
            right.push(num);
            left.push(right.top());
            right.pop();
        } 
        flag = !flag;
    }
    
    double findMedian() {
        if(flag == 0) return (left.top() + right.top() * 1.0) / 2;
        else return right.top();
    }
};

/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder* obj = new MedianFinder();
 * obj->addNum(num);
 * double param_2 = obj->findMedian();
 */

---------------------------------------一刷---------------------------------------

题目描述

在这里插入图片描述

解法

双优先队列(堆)法
创建一个大根堆存储数组的较小值和一个小根堆存储数组的较大值,可以发现如果数字的个数为偶数
中位数将等于两者的堆顶元素的平均数,为奇数时,通过我们的维护使得小根堆的堆顶元素为中位数

class MedianFinder {
public:
    int flag;
    priority_queue <int, vector<int>, less<int> > left;
    priority_queue <int, vector<int>, greater<int> > right;
    /** initialize your data structure here. */
    MedianFinder() {
        flag = 0;
    }
    
    void addNum(int num) {
        //左大根堆根右小根堆大小相同,使维持小根堆大小为大根堆+1
        //大根堆的最大元素进入小根堆
        //此时为奇数个数情况
        if(left.size() == right.size()) {
            left.push(num);
            right.push(left.top());
            left.pop();
        }
        //小根堆大小为大根堆+1,使两者大小相同
        //
        //此时为偶数个数字情况
        else {
            right.push(num);
            left.push(right.top());
            right.pop();
        }
        flag = !flag;

    }
    
    double findMedian() {
        return flag? right.top() : (right.top()+left.top())/2.0;
    }
};

/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder* obj = new MedianFinder();
 * obj->addNum(num);
 * double param_2 = obj->findMedian();
 */

时间复杂度:返回平均数O(1) 增加元素O(logN)
空间复杂度O(N)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值