您的位置:首页 > Web前端

剑指Offer-41:数据流中的中位数

2018-03-11 10:48 330 查看

题目:

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

链接:

剑指Offer(第2版):P214

思路标签:

算法:堆排序

数据结构:最大堆最小堆vector

解答:

基于最大、最小堆的方法(时间复杂度:O(n)插入,O(1)查找)

其他如:排序数组、排序链表、二叉搜索树等方法与时间复杂度比较参见书中内容。

因为我们寻找的是中位数,只要找到左边最大的数,右边最小的数,即可。所以可以分别使用最大最小堆来实现;

同时,因为是中位数,所以需要保证两个堆中的数据平衡;

为了实现平衡分配,可以在当前总数据数目是偶数时把新数据插入最小堆,奇数时插入最大堆;

以插入最大堆为例,如果当前插入的数据小于最大堆的最大值,那么将其插入到最大堆,并弹出最大堆的最大值,压入最小堆。这样就保证了最小堆中的数字都大于最大堆中的数字。同理插入最小堆的过程相对应。

class Solution {
public:
void Insert(int num)
{
if(((min.size()+max.size()) & 1) == 0){
if(max.size() > 0 && num < max[0]){
max.push_back(num);
push_heap(max.begin(), max.end(), less<int>());
num = max[0];
pop_heap(max.begin(), max.end(), less<int>());
max.pop_back();
}
min.push_back(num);
push_heap(min.begin(), min.end(), greater<int>());
}
else{
if(min.size() > 0 && num > min[0]){
min.push_back(num);
push_heap(min.begin(), min.end(), greater<int>());
num = min[0];
pop_heap(min.begin(), min.end(), greater<int>());
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 median = 0;
if((size & 1) == 1)
median = (double)min[0];
else
median = ((double)min[0] + (double)max[0]) /2;

return median;
}

private:
vector<int> min, max;

};


C++相关

STL–heap概述

https://www.cnblogs.com/likui360/p/6364896.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息