剑指offer实践 ——41.数据流中的中位数(python版)

文章目录



题目

数据流中的中位数
在这里插入图片描述


一、思路

数据是流式的从数据容器中读取出来的,如果我们将它存储到一个数组中,需要查找中位数的时候,排序并查找,则排序需要的时间理想是O(logn),查找需要的时间O(1)。
如果将流式的数据存储到排序的数组中,插入需要O(n)的时间,但是查找需要O(1)。
思考一下中位数的特点。
中位数的左边数字均小于中位数。
中位数的右边数字均大于中位数。
中位数左右两边的数字数量相等(偶数个长度的时候中位数取中间2位的平均值)

因此如果我们在读取流式数据的时候,维护两个堆。
一个小顶堆存储右半部分大于中位数的数据。
一个大顶堆存储左半部分小于中位数的数据。
当左右两个顶堆的长度相同时,插入左边的大顶堆。
当左右两个顶堆的长度不同时,插入右边的小顶堆。

基于这个思路需要思考更细致的地方:
1.如果两个顶堆长度相同,需要插入左边,但此时插入的数据大于右边小顶堆的最小值,则这个值应该插入右边的小顶堆,并把右边小顶堆的最小值推入左边大顶堆。

2.如果两个顶堆长度相同,需要插入右边,但此时插入的数据小于左边大顶堆的最大值,则这个值应该插入左边的大顶堆,并把左边大顶堆的最大值推入右边的小顶堆。

class MedianFinder(object):

    def __init__(self):
        """
        initialize your data structure here.
        """
        # 保存左半部分的最大堆
        self.left = []
        # 保存右半部分的最小堆
        self.right = []


    def addNum(self, num):
        """
        :type num: int
        :rtype: None
        """
        if len(self.left) == len(self.right):
            heapq.heappush(self.right, num)
            heapq.heappush(self.left, -heapq.heappop(self.right))
        else:
            heapq.heappush(self.left, -num)
            heapq.heappush(self.right, -heapq.heappop(self.left))



    def findMedian(self):
        """
        :rtype: float
        """
        if len(self.left) == 0:
            return 0
        if len(self.left) == len(self.right):
            mid = (self.right[0] - self.left[0]) / 2.0
        else:
            mid = -self.left[0]
        return mid
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值