码迷,mamicode.com
首页 > 其他好文 > 详细

Find Median from Data Stream

时间:2015-12-12 21:42:53      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:

常规方法 超时

class MedianFinder {
    vector<int> coll;
public:
    MedianFinder(){
        
    }
    void heapfu(vector<int>& coll,int idx,int max){
        int left=2*idx+1,right=2*idx+2;
        int largest=idx;
        if(left<max&&coll[left]>coll[idx])  largest=left;
        if(right<max&&coll[largest]<coll[right])  largest=right;
        if(largest!=idx){
            swap(coll[largest],coll[idx]);
            heapfu(coll,largest,max);
        }
    }
    // Adds a number into the data structure.
    void addNum(int num) {
        coll.push_back(num);
        swap(coll[0],coll[coll.size()-1]);
        for(int i=coll.size()/2-1;i>=0;i--)   
            heapfu(coll,i,coll.size());
    }

    // Returns the median of current data stream
    double findMedian() {
        if(coll.size()==2) return (double)(coll[0]+coll[1])/2;
        if(coll.size()==0)  return 0;
        if(coll.size()==1)  return coll[0];
        if(coll.size()%2 == 0){
            for(int i=0;i<=coll.size()/2-1;i++){
                swap(coll[0],coll[coll.size()-1-i]);
                heapfu(coll,0,coll.size()-i-1);
            }
            int a=coll[0];
            swap(coll[0],coll[coll.size()-1-coll.size()/2-1]);
            heapfu(coll,0,coll.size()-coll.size()/2-1-1);
            return (double)(a+coll[0])/2;
        } 
        else{
            for(int i=0;i<=coll.size()/2;i++){
                swap(coll[0],coll[coll.size()-1-i]);
                heapfu(coll,0,coll.size()-i-1);
            }
            return (double)coll[0];
        }
    }
};

// Your MedianFinder object will be instantiated and called as such:
// MedianFinder mf;
// mf.addNum(1);
// mf.findMedian();

 

两个优先队列  数组如果是 123 789

这样存储 3,2,1  和 7,8,9

class MedianFinder {
    priority_queue<int, vector<int>, greater<int>> min_heap;
    priority_queue<int, vector<int>, less<int>> max_heap;
public:
    // Adds a number into the data structure.
    void addNum(int num) {
        if(min_heap.empty()||num>min_heap.top())
            min_heap.push(num);
        else
            max_heap.push(num);
        if(min_heap.size()>max_heap.size()+1){
            max_heap.push(min_heap.top());
            min_heap.pop();
        }
        else if(max_heap.size()>min_heap.size()){
            min_heap.push(max_heap.top());
            max_heap.pop();
        }
    }

    // Returns the median of current data stream
    double findMedian() {
        return min_heap.size()==max_heap.size()? 0.5*(min_heap.top()+max_heap.top()):min_heap.top();
    }
};

 Q:如果要求第n/10个数字该怎么做?
A:改变两个堆的大小比例,当求n/2即中位数时,两个堆是一样大的。而n/10时,说明有n/10个数小于目标数,9n/10个数大于目标数。所以我们保证最小堆是最大堆的9倍大小就行了。

Find Median from Data Stream

标签:

原文地址:http://www.cnblogs.com/yanqi110/p/5041848.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!