[leetcode] 295. Find Median from Data Stream

题目:Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.

Examples:
[2,3,4] , the median is 3

[2,3], the median is (2 + 3) / 2 = 2.5

Design a data structure that supports the following two operations:

void addNum(int num) - Add a integer number from the data stream to the data structure.
double findMedian() - Return the median of all elements so far.
For example:

add(1)
add(2)
findMedian() -> 1.5
add(3)
findMedian() -> 2
题意:
给你一堆数,找出这些数的中位数,如果是偶数个数字,那么中位数就是最中间两个数字的平均值。实现两个函数,一个是往数据结构中加入某个整数,一个函数是求出当前这堆数据流的平均值。
思路:
最简单的思维方式是,向一个容器里面加入数字,然后进行排序,时间复杂度是O(n(log(n)),然后花O(1)的时间找出中位数。
这里可以考虑使用堆这种数据结构,使用一个最大堆,使用一个最小堆,如果保证最大堆中的元素都小于等于最小堆的元素,并且如果两者元素相同,那么中位数就是最大堆的堆顶元素和最小堆的堆顶元素的平均值。数据结构在加入数字的时候保证两点:

  1. 最大堆的元素都小于等于最小堆的元素。
  2. 两者元素个数相差不超过1。

具体实现的话,使用C++中的优先级队列,因为优先级队列就是使用的堆得操作。priority_queue的默认使用的是最大堆,即堆顶元素是最大值。最小堆需要我们加入模板参数,priority_queue

class MedianFinder {
public:

    MedianFinder() {
        num_small = 0;
        num_big = 0;
    }
    // Adds a number into the data structure.
    void addNum(int num) {
        if(num_small == num_big) {
            if(num_small == 0) {
                small.push(num);
            }
            else {
                if(big.top() < num) {
                    int temp = big.top();
                    big.pop();
                    small.push(temp);
                    big.push(num);
                }
                else small.push(num);
            }
            num_small++;
        }
        else {
            if(small.top() > num) {
                int temp = small.top();
                small.pop();
                big.push(temp);
                small.push(num);
            }
            else big.push(num);
            num_big++;
        }

    }

    // Returns the median of current data stream
    double findMedian() {
        if(num_small == 0)return 0;
        else if(num_small > num_big)return small.top();
        else return (small.top() + big.top())/2.0;
    }
private:
    priority_queue<int> small;
    priority_queue<int, std::vector<int>, std::greater<int>> big;
    int num_small;
    int num_big;
};

// Your MedianFinder object will be instantiated and called as such:
// MedianFinder mf;
// mf.addNum(1);
// mf.findMedian();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值