Continuous Median:设计一个在线算法,可以实时计算输入流的中位数。
根据中位数的定义,分为两种情况:
- 当序列长度为偶数时,中位数是排序后最中间两个数的平均值
- 当序列长度为奇数时,中位数是排序后最中间的值
如果可以很快的得到最中间的两个值,那么就能很快地计算中位数,因此我们使用两个堆,一个最大堆,一个最小堆,最大堆保存左一半的元素,最小堆保存最右边的元素,这样在总长度为偶数时可以很快的计算中位数。当总长度为奇数时,只要一直维护右边比左边多一个或者左边比右边多一个的关系就好了。
priority_queue的第三个参数的默认值为less<T>,即当两个元素a和b满足a < b时a会在b的左边,而top()返回根据less确定的关系的右边的元素,也就是最大值。
class MedianFinder {
priority_queue<int, vector<int>, less<int>> MaxHeap;
priority_queue<int, vector<int>, greater<int>> MinHeap;
public:
/** initialize your data structure here. */
MedianFinder() {
}
void addNum(int num) {
size_t size = MaxHeap.size() + MinHeap.size();
if(size == 0){
MinHeap.push(num);
}
else if(size % 2 == 1){
int right = MinHeap.top();
if(num > right){
MinHeap.pop();
MaxHeap.push(right);
MinHeap.push(num);
}
else{
MaxHeap.push(num);
}
}
else{
int left = MaxHeap.top(), right = MinHeap.top();
if(num <= left){
MaxHeap.pop();
MaxHeap.push(num);
MinHeap.push(left);
}
else if(num >= right){
MinHeap.push(num);
}
else{
MinHeap.push(num);
}
}
}
double findMedian() {
size_t size = MaxHeap.size() + MinHeap.size();
if(size % 2 == 1) return static_cast<double>(MinHeap.top());
else return (MaxHeap.top() + MinHeap.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();
*/
本文介绍了一种在线算法ContinuousMedian,能够实时计算输入流的中位数。通过使用最大堆和最小堆,该算法能在数据流长度为奇数或偶数时快速找到中位数,适用于需要实时统计中位数的场景。
743

被折叠的 条评论
为什么被折叠?



