• 解题报告: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.

    题目分析:

    题目说的很清楚,需要设计一个数据结构,实现插入以及寻找中位数的功能。感觉还是蛮简单的,于是很快写了用vector写了一个。结果OJ显示超时了,看了一下超时的样例,太变态了,一直在插入,寻找......超时原因就是,频繁的插入,使得vector一直在重新分配内存,而且多次全部进行排序成本太高。

     1 class MedianFinder {
     2 public:
     3     std::vector<int> m_num;
     4     // Adds a number into the data structure.
     5     void addNum(int num) {
     6         m_num.push_back(num);
     7     }
     8 
     9     // Returns the median of current data stream
    10     double findMedian() {
    11         sort(m_num.begin(),m_num.end());
    12         int n = m_num.size();
    13         return (m_num[n/2] + m_num[(n-1)/2])/2;
    14     }
    15 };
    16 
    17 // Your MedianFinder object will be instantiated and called as such:
    18 // MedianFinder mf;
    19 // mf.addNum(1);
    20 // mf.findMedian();
    View Code

    考虑使用其他的数据结构。尝试一下STL中自带可排序的数据结构set,set中不能出现重复元素,考虑使用multi_set。而且题目中只关心中间的两个数,可以用两个multiset分别存放较小的部分和较大的部分,只要保证两边的容量保持平衡即可。提交之后,可以AC。除了set之外还可以考虑使用,优先队列,只要可以进行排序的stl容器都可以成功实现这个功能。

    class MedianFinder {
    public:
        std::multiset<int> m_left;
        std::multiset<int> m_right;
        // Adds a number into the data structure.
        void addNum(int num) {
            if (m_left.size() == m_right.size())         //判断两边容量大小
            {
                if (m_right.size()&&num > *m_right.begin())     //如果右边不为空,且新插入的值比右边最小值大,进行调整
                {                                               //将右边的最小值放入左边,新值插入右边
                    m_right.insert(num);
                    int temp = *m_right.begin();
                    m_left.insert(temp);
                    m_right.erase(m_right.begin());
                }
                else 
                    m_left.insert(num);
            }
            else                                       
            {
                if (num < *m_left.rbegin())                      //同样进行判断,如果比左边最大值小,插入左边,进行调整
                {
                    m_left.insert(num);
                    int temp = *m_left.rbegin();
                    m_right.insert(temp);
                    m_left.erase(--m_left.end());
                }
                else 
                    m_right.insert(num);
            }  
        }
    
        // Returns the median of current data stream
        double findMedian() {
            return m_left.size()==m_right.size()?(*m_left.rbegin() + *m_right.begin())/(double)2:*m_left.rbegin(); 
        }
    };
    View Code
  • 相关阅读:
    【重点推荐】五美凡生论
    语言哲学宣言2018
    四要同环图
    知识分子必须毫不留情反对一切“教养阶层”
    世界上任何一件事的五个模块
    Web 在线制表工具稳定吗?和桌面报表工具对比哪个好用?
    Web 在线制表工具稳定吗?和桌面报表工具对比哪个好用?
    有没有简单易用的数据挖掘工具?
    BI、OLAP、多维分析、CUBE 这几个词是什么关系?
    传说中的中国复杂报表都长什么样?有什么特点?
  • 原文地址:https://www.cnblogs.com/Jueis-lishuang/p/5071778.html
Copyright © 2020-2023  润新知