leetcode[每日一题]295. 数据流的中位数

295. 数据流的中位数

题目描述
中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。
例如,
[2,3,4] 的中位数是 3
[2,3] 的中位数是 (2 + 3) / 2 = 2.5
设计一个支持以下两种操作的数据结构:
void addNum(int num) - 从数据流中添加一个整数到数据结构中。
double findMedian() - 返回目前所有元素的中位数。
示例:
addNum(1)
addNum(2)
findMedian() -> 1.5
addNum(3)
findMedian() -> 2
题解(来自评论区Alien-Leon):在数据流中,数据会不断涌入结构中,那么也就面临着需要多次动态调整以获得中位数。 因此实现的数据结构需要既需要快速找到中位数,也需要做到快速调整。

首先能想到就是二叉搜索树,在平衡状态下,树顶必定是中间数,然后再根据长度的奇偶性决定是否取两个数。

此方法效率高,但是手动编写较费时费力。

根据只需获得中间数的想法,可以将数据分为左右两边,一边以最大堆的形式实现,可以快速获得左侧最大数, 另一边则以最小堆的形式实现。其中需要注意的一点就是左右侧数据的长度差不能超过1。 这种实现方式的效率与AVL平衡二叉搜索树的效率相近,但编写更快
代码:

class MedianFinder {
public:
    priority_queue <int,vector<int>,greater<int> > r;//右边小顶堆
    priority_queue <int,vector<int>,less<int> > l;//左边大顶堆
    /** initialize your data structure here. */
    MedianFinder() {
    }
    void addNum(int num) {
        int l1 = l.size();
        int l2 = r.size();
        if(l1==l2){
            if(r.empty()||num<=r.top())
                l.push(num);
            else{
                l.push(r.top());
                r.push(num);
                r.pop();
            }
        }
        else{
            if(num<l.top()){
                r.push(l.top());
                l.push(num);
                l.pop();
            }
            else
                r.push(num);
        }
    }
    double findMedian() {
        int l1 = l.size();
        int l2 = r.size();
        if(l1==l2)
           return (l.top()+r.top())/2.0;
        else
            return l.top();
    }
};
/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder* obj = new MedianFinder();
 * obj->addNum(num);
 * double param_2 = obj->findMedian();
 */

附一个看完题解后的思路和优先队列priority_queue学习
左边大顶堆 右边小顶堆 大顶堆最大<小顶堆最小
优先队列学习

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值