【经典算法题】数据流的中位数

【经典算法题】数据流的中位数

Leetcode 0295 数据流的中位数

题目描述:Leetcode 0295 数据流的中位数

在这里插入图片描述

分析

  • 本题的考点:对顶堆
  • 本题考察数据结构:对顶堆。如下图:

在这里插入图片描述

  • 当我们调用findMedian()时,根据up.size()+down.size()的奇偶性返回对应的结果,如果为奇数,则返回down的堆顶元素,否则返回updown堆顶元素的平均值。

  • 当我们调用addNum(x)函数时

    (1)如果down为空或者x小于等于down堆顶元素时,向down中插入数据x,并调整downup,保证down中元素和up中元素个数相同或者多一个;

    (2)否则down非空并且x大于down堆顶元素,则向up中插入数据x,并调整downup,保证up中元素个数和不能多于up中元素个数。

代码

  • C++
class MedianFinder {
public:

    priority_queue<int> down;  // 大根堆
    priority_queue<int, vector<int>, greater<int>> up;  // 小根堆

    MedianFinder() {

    }
    
    void addNum(int x) {
        if (down.empty() || x <= down.top()) down.push(x);
        else up.push(x);

        if (up.size() > down.size()) down.push(up.top()), up.pop();
        if (down.size() > up.size() + 1) up.push(down.top()), down.pop();
    }
    
    double findMedian() {
        if ((down.size() + up.size()) % 2) return down.top();
        else return (down.top() + up.top()) / 2.0;
    }
};
  • Java
class MedianFinder {

    PriorityQueue<Integer> up = new PriorityQueue<>();  // 小顶堆
    PriorityQueue<Integer> down = new PriorityQueue<>((o1, o2) -> o2 - o1);  // 大顶堆

    /** initialize your data structure here. */
    public MedianFinder() {

    }

    public void addNum(int num) {
        if (down.isEmpty() || num <= down.peek()) {
            down.add(num);
            if (down.size() > up.size() + 1) {
                up.add(down.peek());
                down.remove();
            }
        } else {
            up.add(num);
            if (up.size() > down.size()) {
                down.add(up.peek());
                up.remove();
            }
        }
    }

    public double findMedian() {
        if ((up.size() + down.size()) % 2 == 1) return down.peek();
        else return (up.peek() + down.peek()) / 2.0;
    }
}

时空复杂度分析

  • 时间复杂度:addNum O ( l o g ( n ) ) O(log(n)) O(log(n))findMedian O ( 1 ) O(1) O(1)n是当前插入的数据数量。

  • 空间复杂度: O ( n ) O(n) O(n)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值