[LeetCode] 295. Find Median from Data Stream @ python

一.题目:
寻找数据流中的中位数,即数据会不断更新,求这个动态过程的中位数.
二.解题思路:
利用最大堆和最小堆实现,控制两个堆的数量相等.
代码如下:

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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值