295.数据流的中位数
题目
中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17例如,
[2,3,4] 的中位数是 3
[2,3] 的中位数是 (2 + 3) / 2 = 2.5
设计一个支持以下两种操作的数据结构:
void addNum(int num) - 从数据流中添加一个整数到数据结构中。
double findMedian() - 返回目前所有元素的中位数。
示例:
addNum(1)
addNum(2)
findMedian() -> 1.5
addNum(3)
findMedian() -> 2
进阶:
如果数据流中所有整数都在 0 到 100 范围内,你将如何优化你的算法?
如果数据流中 99% 的整数都在 0 到 100 范围内,你将如何优化你的算法?
方法
方法1:两个堆
采用两个堆,左半部分smaller是最大堆,右半部分larger是最小堆,每个堆都包含数组一半的元素。
smaller的长度总是保持n/2,larger的长度是n/2或n/2+1,这取决于n的奇偶性。
在添加新元素之前,有两种情况(一共有n个元素,k=n/2)1
2(1) length of (small, large) == (k, k)
(2) length of (small, large) == (k, k + 1)
添加新元素后,一共包含n+1个元素1
2(1) length of (small, large) == (k, k + 1)
(2) length of (small, large) == (k + 1, k + 1)
第一种情况,larger会多一个元素,smaller会长度保持不变,但是不能直接将新元素添加到larger。应该将新元素push到smaller,再pop出最大元素,并将其push到larger
第二种情况,smaller会多一个元素,larger会长度保持不变,但不能直接将新元素添加到smaller。应该将新元素push到larger,再pop出最小元素,并将其push到smaller。
1 | from heapq import * |
1 | from heapq import heappush,heappop |
- Leetcode Discussion-add-O(1)-find)
方法2
1 | class MedianFinder(object): |