牛客刷题数据流之数据流中的中位数

题目描述

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

牛客链接:

https://www.nowcoder.com/practice/9be0172896bd43948f8a32fb954e1be1?tpId=13&&tqId=11216&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

解题思路:

有两种方式
第一种,用vector特性,每输入一个数字都插入在合适的位置
第二种,设置一个小顶堆和大顶堆,主要的思想是:因为要求的是中位数,那么这两个堆,大顶堆用来存较小的数,从大到小排列;小顶堆存较大的数,从小到大的顺序排序*,显然中位数就是大顶堆的根节点与小顶堆的根节点和的平均数。

代码一:
插入时间复杂度为o(n),得到中位数的时间复杂度为o(1)

class Solution {
public:
    vector<int> sortNum;
    void Insert(int num)
    {
        if (sortNum.size() == 0) {
            sortNum.push_back(num);
            return ;
        }
        int len = sortNum.size();
        for(int i=0; i<len; i++) {
            if(num>sortNum[i]) {
                sortNum.insert(sortNum.begin()+i,num);
                return;
            }
        }
        sortNum.push_back(num);
        return ;
    }

    double GetMedian()
    { 
        int len = sortNum.size();
        double mid;
        if (len%2 == 0) {
            mid = (sortNum[len/2-1]+sortNum[len/2])/2.0;
        } else {
            mid = sortNum[len/2];
        }
        return mid;
    }

};

代码二:
插入时间复杂度为o(logn),得到中位数的时间复杂度为o(1)

class Solution {
public:
    //定义小顶堆,存后半部分数据
    priority_queue <int,vector<int>,greater<int> > minHeap; 
    //定义大顶堆,存前半部分数据
    priority_queue <int,vector<int>,less<int> >maxHeap;
    int count = 0;
    void Insert(int num)
    {
        count++;
        //若存的为第偶数个数据,插入到小顶堆
        if(count%2 == 0) {
            //先将数据存入大顶堆,再将大顶堆的最大值存入小顶堆
            maxHeap.push(num);
            minHeap.push(maxHeap.top());
            maxHeap.pop();
        } else {
            //若存的为第奇数个数据,插入到大顶堆
            //先将数据存入小顶堆,再将小顶堆的最小值存入大顶堆
            minHeap.push(num);
            maxHeap.push(minHeap.top());
            minHeap.pop();
        }
    }

    double GetMedian()
    { 
       double mid = 0.0;
       if(maxHeap.size() == 0) return mid;
       if (count%2 == 0) {
           mid = (maxHeap.top() + minHeap.top())/2.0;
       } else {
           mid = maxHeap.top();
       }
       return mid;
    }

};

注意点:
vector.insert()
大顶堆和小顶堆

参考链接:
c++优先队列(priority_queue)用法
https://www.cnblogs.com/huashanqingzhu/p/11040390.html

©️2020 CSDN 皮肤主题: 黑客帝国 设计师:上身试试 返回首页