Find Median from Data Stream

常规方法 超时

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倍大小就行了。

上一篇:关于HTTP_CLIENT_IP,HTTP_X_FORWAR


下一篇:HDU 1556 Color the ball(线段树区间更新)