295. 数据流的中位数
中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。
- 例如
arr = [2,3,4]
的中位数是3
。 - 例如
arr = [2,3]
的中位数是(2 + 3) / 2 = 2.5
。
实现 MedianFinder 类:
MedianFinder()
初始化MedianFinder
对象。void addNum(int num)
将数据流中的整数num
添加到数据结构中。double findMedian()
返回到目前为止所有元素的中位数。与实际答案相差10-5
以内的答案将被接受。
示例 1:
输入
["MedianFinder", "addNum", "addNum", "findMedian", "addNum", "findMedian"]
[[], [1], [2], [], [3], []]
输出
[null, null, null, 1.5, null, 2.0]
解释
MedianFinder medianFinder = new MedianFinder();
medianFinder.addNum(1); // arr = [1]
medianFinder.addNum(2); // arr = [1, 2]
medianFinder.findMedian(); // 返回 1.5 ((1 + 2) / 2)
medianFinder.addNum(3); // arr[1, 2, 3]
medianFinder.findMedian(); // return 2.0
解题思路
声明一个大顶堆和一个小顶堆
大顶堆负责放置较小的部分,小顶堆负责放置较大的部分
列表大小为偶数时,大顶堆和小顶堆分别返回各自堆顶元素,即可得到中位数
列表大小为奇数时,大顶堆多放置一个元素,返回多出的这个元素即是中位数(即返回大顶堆堆顶元素)
add 操作思路:
- 假设当前大顶堆和小顶堆存放的元素分别为 1、2 和 3、4,后续需要加入 5
- 加入前需要判断当前堆里的元素个数是奇还是偶
- 如果是偶数,则放入小顶堆中,并将当前小顶堆的堆顶元素取出放到大顶堆中 => [1, 2, 3] 和 [4, 5]
- 如果是奇数,则放入大顶堆中,并将当前大顶堆的堆顶元素取出放到小顶堆中
- 如再进行加入 0 => [0, 1, 2] 和 [3, 4, 5]