题解 | #数据流中的中位数#

数据流中的中位数

http://www.nowcoder.com/practice/9be0172896bd43948f8a32fb954e1be1

由于题目中没有对空间复杂度和时间复杂度做要求,所以上来先考虑较为直接的解法。
建立一个数组用于保存数据流,每次插入数据都将数据存入数组中,在调用获取中位数的方法时,先调用sort对数组进行排序,再获得中位数。

class Solution {
public:
    void Insert(int num) {
        array.push_back(num);
    }

    double GetMedian() { 
        sort(array.begin(),array.end());
        if(array.size()%2){
            return double(array.at((array.size() - 1)/2));
        }
        else{
            return (array.at((array.size() - 1)/2)+array.at((array.size() - 1)/2 + 1))/2.0;
        }
    }
private:
    vector<int> array;
};



注意到题目中涉及到堆的算法,考虑使用堆排序来解决。
选择使用priority_queue的队列,即优先队列,这个数据结构会根据优先级为队列内的元素进行排序,而排序使用的正是堆排序。
所以虽然说使用优先队列能跟堆扯上点关系,但编码过程中的思维逻辑是不涉及堆的。
基本思想很简单,维护两个优先队列,可以默认它们始终保持有序,而不需要认为排序。其中一个队列按升序排列,另一队列按降序排列,使升序队列的最小值永远大于降序队列的最大值。
在插入数据时,轮流插入升序队列与降序队列,当插入一个队列时不直接插入,而是先将其插入另一队列,在将另一队列的队头插入该队列,这样保证两个队列的大小关系。
这样构建的两个队列,其对头元素必定位于输入数列的中位数位置。

这种做法使用了priority_queue自带的内部排序,其实现方法是堆排序,其实跟手动调用sort的结果相差不多。比较重要的思想是那两个队列的关系。

class Solution {
public:
    void Insert(int num) {
        if(control){
            up.push(num);
            int temp = up.top();
            up.pop();
            down.push(temp);
        }
        else{
            down.push(num);
            int temp = down.top();
            down.pop();
            up.push(temp);
        }
        control = !control;
    }

    double GetMedian(){
        if(control){
            return double(up.top());
        }
        else{
            return (up.top() + down.top())/2.0;
        }
    }
private:
    priority_queue<int> up;
    priority_queue<int, vector<int>, greater<int>> down;
    bool control = false;
};
全部评论

相关推荐

shtdbb_:还不错,没有让你做了笔试再挂你
点赞 评论 收藏
分享
拉丁是我干掉的:把上海理工大学改成北京理工大学。成功率增加200%
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务