剑指 Offer 41. 数据流中的中位数

Posted lxy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指 Offer 41. 数据流中的中位数相关的知识,希望对你有一定的参考价值。

题目链接:剑指 Offer 41. 数据流中的中位数

方法一:插入排序

解题思路

每次添加一个数字时,通过插入排序添加,需要返回中位数时,根据元素个数进行返回。

代码

class MedianFinder 
private:
    vector<int> nums;
public:
    /** initialize your data structure here. */
    MedianFinder() 
    
    
    void addNum(int num) 
        nums.push_back(num);
        for (int i = nums.size() - 1; i > 0; i -- ) 
            if (nums[i] < nums[i - 1]) swap(nums[i], nums[i - 1]);
            else break;
        
    
    
    double findMedian() 
        int cnt = nums.size();
        if (cnt == 0) return NULL;
        int mid = cnt / 2;
        if (cnt % 2 == 0) return (nums[mid] + nums[mid - 1]) / 2.0;
        else return nums[mid];
    
;

复杂度分析

执行用时:1360 ms, 在所有 C++ 提交中击败了5.04%的用户
内存消耗:40.7 MB, 在所有 C++ 提交中击败了59.16%的用户
通过测试用例:18 / 18
\\(addNum()\\):时间复杂度为\\(O(n)\\),空间复杂度为\\(O(1)\\)
\\(findMedian()\\):时间复杂度为\\(O(1)\\),空间复杂度为\\(O(1)\\)

方法二:优先队列

解题思路

通过优先队列维护两个数组\\(queMin\\)\\(queMax\\)\\(queMin\\)保存数据流中较小的一部分数(从大到小),\\(queMax\\)保存数据流中较大的一部分数(从小到大),\\(queMax.size() - queMin.size() == 0 || 1\\),则样\\(queMin.top()\\)\\(queMax.top()\\)就是数据流中间的\\(1\\)个数中间的\\(2\\)个数

代码

class MedianFinder 
private:
    priority_queue<int, vector<int>, less<int>> queMin;
    priority_queue<int, vector<int>, greater<int>> queMax;
public:
    /** initialize your data structure here. */
    MedianFinder() 

    
    
    void addNum(int num) 
        if (queMin.empty() || num < queMin.top()) 
            queMin.push(num);
            if (queMax.size() + 1 < queMin.size())  // queMax元素数量少于queMin元素数量超过1个
                queMax.push(queMin.top()); // 将queMin的最大值转移到queMax中,保持平衡
                queMin.pop();
            
         else 
            queMax.push(num);
            if (queMax.size() > queMin.size())  // queMax元素数量超过queMin元素数量
                queMin.push(queMax.top()); // 将queMax的最小值转移到queMin中,保持平衡
                queMax.pop();
            
        
    
    
    double findMedian() 
        if (queMin.size() > queMax.size()) return queMin.top();
        return (queMin.top() + queMax.top()) / 2.0;
    
;

复杂度分析

执行用时:84 ms, 在所有 C++ 提交中击败了93.98%的用户
内存消耗:40.7 MB, 在所有 C++ 提交中击败了33.52%的用户
通过测试用例:18 / 18
\\(addNum()\\):时间复杂度为\\(O(logn)\\),空间复杂度为\\(O(1)\\)
\\(findMedian()\\):时间复杂度为\\(O(1)\\),空间复杂度为\\(O(1)\\)

剑指offer数据流中的中位数

题目链接:数据流中的中位数

 

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

 

题解:啊我这题用暴力做的。。正解应该是最大堆最小堆。。和之前一个题一样。后面再补。

暴力就是sort一下找中位数。

 

代码:

class Solution {
public:
    vector<int> number;
    void Insert(int num)
    {
        number.push_back(num);
    }

    double GetMedian()
    { 
        sort(number.begin(),number.end());
        int len = number.size();
        double ans;
        if(len % 2)
            ans = (double)number[len/2];
        else    
            ans = (double)(number[len/2-1]+number[len/2])/2;
        return ans;
    }

};

 

以上是关于剑指 Offer 41. 数据流中的中位数的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer41. 数据流中的中位数

剑指offer41数据流中的中位数

剑指Offer面试题41. 数据流中的中位数

剑指Offer面试题41. 数据流中的中位数

剑指 Offer 41. 数据流中的中位数

每日一题 - 剑指 Offer 41. 数据流中的中位数