BM48 数据流中的中位数(python)

题目

牛客网链接
持续输入数据,数据均为正,每输入一个数据,输出所有已输入数据的中位数
数据总数为奇数则输出最中间的数,为偶数则输出最中间两数平均值
在这里插入图片描述

思路

维护两个堆:
大根堆maxHeap,保存较小的一半数
小根堆minHeap,保存较大的一半数
当有一个新数字输入,为了保持两个堆分别保存一半数量的元素:

  1. 若两堆元素个数相等,加入大根堆
  2. 若上次加入了大根堆,则本次加入小根堆

每次加入新元素后,检查大顶堆顶元素是否大于小顶堆顶元素,若是则交换两个堆顶元素

实现

heapq实现小顶堆,大顶堆

python中heapq模块可以将列表转化为堆,默认为小顶堆;若要实现大顶堆,可以在插入元素时取相反数,即可用小顶堆模拟大顶堆

heappushpop和heappush实现本题中交换堆顶元素操作

每次加入新元素后,检查大顶堆顶元素是否大于小顶堆顶元素,若是则交换两个堆顶元素

  • heappush:将列表作为小根堆,插入元素并调整
  • heappushpop:向堆中插入元素并调整,再弹出堆顶元素

向堆A插入元素之前,使用heappushpop,将元素先插入另一个堆B,再取B堆顶元素,插入A,即可实现

代码

from heapq import heappush,heappushpop


class Solution:
    def __init__(self):
        # 维护一个大顶堆和一个小顶堆
        # heapq使用的是小顶堆,要实现大顶堆,在加入元素时给元素取反
        self.maxHeap = []
        self.minHeap = []

    def Insert(self, num):
        # 当有新元素插入,优先加入大顶堆;若大顶堆顶元素比小顶堆顶大则交换
        if len(self.maxHeap) == len(self.minHeap):
            heappush(self.maxHeap, -heappushpop(self.minHeap,num))

        # 上次加入了大顶堆,本次加入小顶堆
        else:
            heappush(self.minHeap, -heappushpop(self.maxHeap,-num))


    def GetMedian(self):
        # 两个堆元素个数相等,返回两个堆顶平均值
        if len(self.maxHeap) == len(self.minHeap):
            return (self.minHeap[0] - self.maxHeap[0]) / 2
        # 大顶堆元素多,返回大顶堆顶
        else:
            return -self.maxHeap[0]

参考链接

https://blog.csdn.net/u010770184/article/details/53349152
https://blog.csdn.net/qq_45880043/article/details/119039260

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值