堆的经典解法
直观方法用数组求解,每次添加元素或查找中位数时对数组排序,分析一下时间复杂度:
- 添加元素时排序addnum复杂度o(n),findmedia复杂度o(1);
- 查询中位数排序,addnum复杂度o(1),findmedia复杂度o(nlogn);
我们改进一下算法,动态维护一个大顶堆和一个小顶堆;大顶堆维护一半元素,小顶堆维护一半;维持大顶堆的堆顶要比维护小顶堆的堆顶小;所以会出现;
- 当小顶堆和大顶堆数据个数一样;
- 当小顶堆和大顶堆数据个数不一样;
代码如下:
class MedianFinder {
private:
priority_queue<int, vector<int>, std::greater<int> > min_heap;
priority_queue<int, vector<int>, std::less<int> > big_heap;
public:
/** initialize your data structure here. */
// 堆的经典解法
MedianFinder() {
}
void addNum(int num) {
if(min_heap.size()==0&&big_heap.size()==0){
min_heap.push(num);
}
else if(min_heap.size()==big_heap.size()){
if(num>=min_heap.top()) min_heap.push(num);
else big_heap.push(num);
}
// 个数不一样时又有两种情况
else{
if(min_heap.size()>big_heap.size()){
if(num>=min_heap.top()) {
int x=min_heap.top();
min_heap.pop();
big_heap.push(x);
min_heap.push(num);
}
else{
big_heap.push(num);
}
}
else {
if(num<=big_heap.top()) {
int x=big_heap.top();
big_heap.pop();
min_heap.push(x);
big_heap.push(num);
}
else{
min_heap.push(num);
}
}
}
}
double findMedian() {
if(min_heap.size()==big_heap.size()) return (min_heap.top()+big_heap.top())/2.0;
return min_heap.size()>big_heap.size()?min_heap.top():big_heap.top();
}
};
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder* obj = new MedianFinder();
* obj->addNum(num);
* double param_2 = obj->findMedian();
*/