数据流中的中位数--使用python内置的heapq模块

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值
链接
方法一

  1. 使用大堆存储左边的值
  2. 使用小堆存储右边的值
  3. 0 <= 保证大堆数据的长度 - 小堆数据的长度 <=1
  4. 数据长度为奇数时, 中位数为大堆堆顶
  5. 在python中只能使用小堆 使用最大堆时存储 -num
  6. 每个添加数据时,先要判断往哪个堆插入 然后balance
import heapq
class MedianFinder:
    def __init__(self):
        """
        initialize your data structure here.
        """
        self.min_heap = []
        self.max_heap = []

    def addNum(self, num: int) -> None:
        if self.max_heap and num >= -self.max_heap[0]:
            # 如果大堆不为空且 num大于大碓顶  应该小堆插入
            heapq.heappush(self.min_heap, num)
        else:
            heapq.heappush(self.max_heap, -num)
        self.balance()

    def balance(self):
        if len(self.min_heap) > len(self.max_heap):
            min_heap_top = heapq.heappop(self.min_heap)
            heapq.heappush(self.max_heap, -min_heap_top)

        elif len(self.max_heap) - len(self.min_heap) > 1:
            max_heap_top = - heapq.heappop(self.max_heap)
            heapq.heappush(self.min_heap, max_heap_top)

    def findMedian(self) -> float:
        if len(self.min_heap) != len(self.max_heap):
            return -self.max_heap[0]
        else:
            return (-self.max_heap[0] + self.min_heap[0]) /2

方法二
思路同方法1, 效率略优于方法1
区别如下:
插入数据时 使用 heapq.heappushpop 不需要显示的balance最大堆和最小堆
最后 最小堆的长度较大 所以为奇数时 输出 最小堆堆顶

class MedianFinder1:
    def __init__(self):
        """
        initialize your data structure here.
        """
        # 初始化大顶堆和小顶堆
        self.max_heap = []
        self.min_heap = []
    def addNum(self, num: int) -> None:
        if len(self.max_heap) == len(self.min_heap):
            # 先加到大顶堆,再把大堆顶元素加到小顶堆
            heapq.heappush(self.min_heap, -heapq.heappushpop(self.max_heap, -num))
        else:  # 先加到小顶堆,再把小堆顶元素加到大顶堆
            heapq.heappush(self.max_heap, -heapq.heappushpop(self.min_heap, num))

    def findMedian(self) -> float:
        if len(self.min_heap) == len(self.max_heap):
            return (-self.max_heap[0] + self.min_heap[0]) / 2
        else:
            return self.min_heap[0]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值