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

Examples: spa

[2,3,4] , the median is 3设计

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

Design a data structure that supports the following two operations:code

  • 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.

题目分析:blog

题目说的很清楚,须要设计一个数据结构,实现插入以及寻找中位数的功能。感受仍是蛮简单的,因而很快写了用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
相关文章
相关标签/搜索