【LeetCode & 剑指offer刷题】查找与排序题3:41 数据流中的中位数(295. Find Median from Data Stream)
【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)
41 数据流中的中位数
题目描述
如何得到一个数据流中的中位数?如果从数据流中读出
奇数个数值,那么
中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
/*
1 2 3 4 [5]
+ [6] 7 8 9 10
大顶堆 + 小顶堆
方法一:用两个堆(stl中的priority_queue)
过程:用于一个大顶堆实现左边容器,小顶堆实现右边容器,根据左边最大数与右边最小数得到中位数
(1) 平均分配
(2) 还要保证大顶堆中所有数据小于小顶堆中元素,比较新数据与大顶堆和小顶堆堆顶元素就知道该放到哪里
插入O(logn) 得到中位数O(1),空间复杂度O(n)
*/
class
Solution
{
private
:
priority_queue
<
int
>
maxheap
;
//stl中默认为大顶堆(联系默认的二叉搜索树,
//根结点较左子树大,中序遍历从小到大,不同的是大顶堆根结点较左右子树都大)
priority_queue
<
int
,
vector
<
int
>,
greater
<
int
>>
minheap
;
//小顶堆
public
:
void
Insert
(
int
num
)
{
if
(
maxheap
.
empty
()
||
num
<
maxheap
.
top
())
maxheap
.
push
(
num
);
//如果新数属于小的一半(左边)
else
minheap
.
push
(
num
);
if
(
maxheap
.
size
()
<
minheap
.
size
())
//保持两边长度一致(左边比右边多一或者左右两边长度一样)
{
maxheap
.
push
(
minheap
.
top
());
minheap
.
pop
();
}
else
if
(
maxheap
.
size
()
>
minheap
.
size
()
+
1
)
{
minheap
.
push
(
maxheap
.
top
());
maxheap
.
pop
();
}
}
double
GetMedian
()
{
return
(
maxheap
.
size
()>
minheap
.
size
())?
maxheap
.
top
():
(
maxheap
.
top
()
+
minheap
.
top
())*
0.5
;
//奇数时,返回中间元素,偶数时,返回中间两个数的平均数,注意浮点数的处理
}
};