---------------------------------二刷2021/1/25-------------------------------
无论我们要放到左边还是右边,都不是直接放num,而是从左/右中拿出那个在规定规则下面一定属于另外一个堆的数字,所以是正确的
class MedianFinder {
public:
int flag = 0;
priority_queue<int, vector<int>, less<int>> left;
priority_queue<int, vector<int>, greater<int>> right;
/** initialize your data structure here. */
MedianFinder() {
}
void addNum(int num) {
//flag初始为0,说明为0是偶数情况
if(flag == 0) {
left.push(num);
right.push(left.top());
left.pop();
}
else {
right.push(num);
left.push(right.top());
right.pop();
}
flag = !flag;
}
double findMedian() {
if(flag == 0) return (left.top() + right.top() * 1.0) / 2;
else return right.top();
}
};
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder* obj = new MedianFinder();
* obj->addNum(num);
* double param_2 = obj->findMedian();
*/
---------------------------------------一刷---------------------------------------
题目描述
解法
双优先队列(堆)法
创建一个大根堆存储数组的较小值和一个小根堆存储数组的较大值,可以发现如果数字的个数为偶数
中位数将等于两者的堆顶元素的平均数,为奇数时,通过我们的维护使得小根堆的堆顶元素为中位数
class MedianFinder {
public:
int flag;
priority_queue <int, vector<int>, less<int> > left;
priority_queue <int, vector<int>, greater<int> > right;
/** initialize your data structure here. */
MedianFinder() {
flag = 0;
}
void addNum(int num) {
//左大根堆根右小根堆大小相同,使维持小根堆大小为大根堆+1
//大根堆的最大元素进入小根堆
//此时为奇数个数情况
if(left.size() == right.size()) {
left.push(num);
right.push(left.top());
left.pop();
}
//小根堆大小为大根堆+1,使两者大小相同
//
//此时为偶数个数字情况
else {
right.push(num);
left.push(right.top());
right.pop();
}
flag = !flag;
}
double findMedian() {
return flag? right.top() : (right.top()+left.top())/2.0;
}
};
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder* obj = new MedianFinder();
* obj->addNum(num);
* double param_2 = obj->findMedian();
*/
时间复杂度:返回平均数O(1) 增加元素O(logN)
空间复杂度O(N)