剑指offer-63.数据流中的中位数

在这里插入图片描述
解题思路:

用大顶堆和小顶堆解决这个问题。

大顶堆就是首元素是最大值;小顶堆则是最小值。
现在设计一个
大顶堆get_max,用于保存比中位数小的数,首元素是最大值;
小顶堆get_min,用于保存大于或等于中位数的数,首元素是最小值。

举个例子
数据流1,2,3,4,5,6
get_max [1,2,3]
get_min [4,5,6]

分类讨论
我们规定get_min要么比get_max的容量大1个,要么等于。

所以,数据流个数是偶数个,我们只要取出get_min的最小值和get_max的最大值,然后相加除以2就是中位数。
假如数据流个数是奇数个,只要取出get_min的最小值就是中位数。

现在考虑插入数据
1 当get_min空的时候,数据插入get_min;
2 当数据num大于等get_min的首元素时,也就是说num大于中位数,那么插入get_min中;
考虑这么一种情况,get_min有4个元素,get_max有3个元素,现在来了一个元素,我们判断插入get_min中,那么get_min有5个元素了,不符合上述的规定,因此我们需要分一个值给get_max,那么就把get_min中的最小值给get_max就可以了。

if(get_min.size()>=get_max.size()+1){
	get_max.push(get_min.top());
	get_min.top();
}

3 除此之外,就是插入get_max,同样的,根据我们的规定,当get_max.size()>get_min.size(),要分一个元素给get_min。


这里补充一下大顶堆、小顶堆的用法
用的容器时
priority_queue<Type, Container, Functional>
Type是元素类型,Container是容器,Functional是哪种顶堆。

priority_queue<int,>
默认等价于
priority_queue<int,vector<int,>,less<int,>>;
less说明所有的元素都比堆顶元素大。
默认大顶堆
greater<int,>是小顶堆,greater说明所有元素都比堆顶元素大。

class Solution {
    priority_queue<int,vector<int>,less<int>> get_max;   //大顶堆,队头放最大值,比中位数小的值
    priority_queue<int,vector<int>,greater<int>> get_min;//小顶堆,队头放最小值,比中位数大的值,小顶堆元素个数>=大顶堆
public:
    void Insert(int num) {
        if(get_min.empty()||num>=get_min.top()){
            //先放进get_min
            get_min.push(num);
            //再看要不要移动元素到get_max
            if(get_min.size()>get_max.size()+1){
                int tmp=get_min.top();
                get_min.pop();
                get_max.push(tmp);
            }
        }else{
            get_max.push(num);
            if(get_max.size()>get_min.size()){
                int tmp=get_max.top();
                get_max.pop();
                get_min.push(tmp);
            }
        }

    }

    double GetMedian() { 
        if(get_min.size()!=get_max.size())
            return get_min.top();
        else
            return (get_min.top()+get_max.top())/2.0;
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值