剑指offer63:数据流中的中位数

题目描述:

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。

本题最开始简单的理解为求中位数,使用的是快排的思想,当数据元素为奇数个时,求第n/2大的数,当元素个数为偶数时,先求n/2个数,然后对右边的求出一个最小值。

看了别人的做法,发现应该把这道题理解为一个在线算法题。关键是使用两个堆,最大化堆存储前n/2个数,最小化堆存储后n/2个数,当元素个数为偶数个时,元素num放入最小化堆中;元素个数为奇数时,元素num放入最大化堆。最终,当元素个数为奇数时,中位数就是最小化堆的堆顶;当元素个数为偶数时,中位数是最小化堆和最大化堆的堆顶的均值。

 class Solution {
private:
vector<int> minHeap; //数组中的后一半元素组成一个最小化堆
vector<int> maxHeap; //数组中的前一半元素组成一个最大化堆
public:
void Insert(int num) {
if(((minHeap.size()+maxHeap.size()) & ) == ) { //偶数数据的情况下,则在最小堆中插入元素
if(maxHeap.size() > && num < maxHeap[]) {
maxHeap.push_back(num);
push_heap(maxHeap.begin(), maxHeap.end(), less<int>());
num=maxHeap[];
pop_heap(maxHeap.begin(), maxHeap.end(), less<int>());
maxHeap.pop_back();
}
minHeap.push_back(num); //把前一半找到的最大值放到后一半中
push_heap(minHeap.begin(), minHeap.end(), greater<int>());
} else {
if(minHeap.size() > && num > minHeap[]) { //奇数数据的情况下,则在最大堆中插入元素
minHeap.push_back(num);
push_heap(minHeap.begin(), minHeap.end(), greater<int>());
num=minHeap[];
pop_heap(minHeap.begin(), minHeap.end(), greater<int>());
minHeap.pop_back();
}
maxHeap.push_back(num); //把后一半找到的最大值放到前一半中
push_heap(maxHeap.begin(), maxHeap.end(), less<int>());
}
} double GetMedian() {
int size=minHeap.size() + maxHeap.size();
if(size==) return -;
if((size&) != ) {
return (double) minHeap[];
} else {
return (double) (maxHeap[] + minHeap[]) / ;
}
}
};
上一篇:iOS加密


下一篇:AES-GCM查表原理