常规方法 超时
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倍大小就行了。