python 数据流中的移动平均值_剑指offer 数据流中的中位数

题目描述

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

解析:emmm 剑指offer分析了一大堆数据结构的时间复杂度。具体如下:

750698dc809ed8b2e606511c040ab3b9.png

73249a3d78d49db94cda14c6c00726fc.png

最后得出结论使用最大最小堆是最优雅的解法,我这里就练习了一下这种方法。要求中位数,我们可以定义一个最大堆,一个最小堆,始终维护两个堆,使最大堆中最大元素小于最小堆中最小元素。

首先要保证数据平均分配到两个堆,因此两个堆中元素数目之差不能超过1,我们可以在数据总数目是偶数时把数据插入最大堆,否则插入最小堆。

然后要保证最大堆中所有元素小于最小堆中所有元素。当总数据量为偶数时,我们应该将数据插入最大堆,此时判断要插入的数据与最小堆中最小元素大小情况,如果插入数据大于最小堆堆顶元素,那么把最小堆堆顶元素取出压入最大堆,将新数据插入最小堆,这就保证了最大堆堆顶元素永远小于最小堆堆顶元素。总数据量为奇数时同理。

这里注意python的heapq模块实现的是最小堆,可以将数据取反压入,模拟最大堆。

from heapq import *
class Solution:
    def __init__(self):
        self.min_s = []
        self.max_s = []
    def Insert(self, num):
        # write code her
        if not self.min_s and not self.max_s:
            heappush(self.max_s, -num)
        elif (len(self.min_s) + len(self.max_s)) & 1 == 0:
            if num > self.min_s[0]:
                tmp = heappop(self.min_s)
                heappush(self.max_s, -tmp)
                heappush(self.min_s, num)
            else:
                heappush(self.max_s, -num)
        elif (len(self.min_s) + len(self.max_s)) & 1 != 0:
            if num < -self.max_s[0]:
                tmp = heappop(self.max_s)
                heappush(self.min_s, -tmp)
                heappush(self.max_s, -num)
            else:
                heappush(self.min_s, num)
    def GetMedian(self, n = None):
        # write code here
        if (len(self.min_s) + len(self.max_s)) & 1 != 0:
            return -self.max_s[0]
        else:
            return (-self.max_s[0] + self.min_s[0]) / 2.0

2019.3.23

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值