一.
下圖是從數組爲0下標開始計算的。
下圖是從數組爲1下標開始計算的。引自《STL源碼剖析》 p173
- 64.數據流中的中位數。《劍指offer》 p286
如何得到一個數據流中的中位數?如果從數據流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從數據流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。
class Solution {
public:
void Insert(int num)
{
if((max.size()+min.size()) % 2 == 0) //數據總數目是偶數,將新的數據放入到最小堆中
{
if(!max.empty() && num < max[0]) //如果新插入的數據比最大堆的最大值要小,那麼就將新數據插入到最大堆中,並將最大堆的最大值彈出,放到最小堆中
{
max.push_back(num);
push_heap(max.begin(),max.end(),less<int>());
pop_heap(max.begin(),max.end(),less<int>()); //彈出最大堆的最大值
num = max.back();
max.pop_back();
}
min.push_back(num);
push_heap(min.begin(),min.end(),greater<int>()); //組建最小堆
}
else //數據總數目是奇數,將新數據放入到最大堆中
{
if(!min.empty()&&num > min[0]) //新插入的數據比最小堆的最小值還要大,那麼就將新插入的數據放入最小堆中,並將最小堆的最小值彈出,放入最大堆中
{
min.push_back(num);
push_heap(min.begin(),min.end(),greater<int>());
pop_heap(min.begin(),min.end(),greater<int>()); //彈出最小堆最小值
num = min.back();
min.pop_back();
}
max.push_back(num);
push_heap(max.begin(),max.end(),less<int>());
}
}
double GetMedian()
{
int size = max.size()+min.size();
if(size == 0)
return 0;
double res = 0;
if(size % 2 == 1)
{
/*
if(min.empty())
res = max[0];
if(max.empty())
res = min[0];*/
res = min[0]; //當只有一個元素,不需要判斷是最大堆還是最小堆,因爲一個數是奇數,一定是放到最小堆中。
}
else
res = (max[0]+min[0])/2;
return res;
}
vector<double> max; //最大堆 //***涉及到浮點運算,原始數據存儲用double
vector<double> min; //最小堆
};