一.题目:
寻找数据流中的中位数,即数据会不断更新,求这个动态过程的中位数.
二.解题思路:
利用最大堆和最小堆实现,控制两个堆的数量相等.
代码如下:
class MedianFinder(object):
def __init__(self):
self.max_heap = [] # for half left
self.min_heap = [] # for half right
def addNum(self, num):
size_left = len(self.max_heap)
size_right = len(self.min_heap)
#如果两个堆都是空的,那么把数字放到最小堆中
if size_left == 0 and size_right == 0:
heapq.heappush(self.min_heap, num)
return
if self.max_heap:
left_val = -self.max_heap[0]
if self.min_heap:
right_val = self.min_heap[0]
#如果两个堆数量相等,那么先考虑把数字放入到最大堆.然后在将排出的堆顶放入到最小堆中
if size_left == size_right:
#如果数字比最大堆中的最大数还大,说明最大堆中排出的堆顶肯定还是它,所以直接把它放入到最小堆中
if num < left_val:
#由于使用的是heapq库,只适用于最小堆,所以我们需要把数字取反
heapq.heappush(self.max_heap, -num)
tmp = heapq.heappop(self.max_heap)
heapq.heappush(self.min_heap, -tmp)
else:
heapq.heappush(self.min_heap, num)
if size_left < size_right:
if num < right_val:
heapq.heappush(self.max_heap, -num)
else:
tmp = heapq.heappop(self.min_heap)
heapq.heappush(self.max_heap, -tmp)
heapq.heappush(self.min_heap, num)
def findMedian(self):
size_left = len(self.max_heap)
size_right = len(self.min_heap)
if size_left == size_right:
return (-self.max_heap[0] + self.min_heap[0])/2.0
elif size_left > size_right:
return float(-self.max_heap[0])
else:
return float(self.min_heap[0])
# Your MedianFinder object will be instantiated and called as such:
# obj = MedianFinder()
# obj.addNum(num)
# param_2 = obj.findMedian()