JZ63 数据流中的中位数

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

示例1
输入:
[5,2,3,4,1,6,7,0,8]
返回值:
"5.00 3.50 3.00 3.50 3.00 3.50 4.00 3.50 4.00 "
说明:
数据流里面不断吐出的是5,2,3…,则得到的平均数分别为5,(5+2)/2,3…

  1. 插入排序:每次插入就进行一次排序,然后取中位数的时候,直接取中间一位或中间两位的平均值即可
class Solution:
    def __init__(self):
        self.matrix = []
    def Insert(self, num):
        if not self.matrix or num > self.matrix[-1]:
            self.matrix.append(num)
        else:
            self.matrix.append(num)
            for i in range(len(self.matrix)-1,0,-1):
                if self.matrix[i] < self.matrix[i-1]:
                    tmp = self.matrix[i]
                    self.matrix[i] = self.matrix[i-1]
                    self.matrix[i-1] = tmp
                else:
                    break

    def GetMedian(self):
        l = len(self.matrix)
        if l % 2 == 0:
            return (self.matrix[l//2-1] + self.matrix[l//2])/2.0
        else:
            return self.matrix[l//2]
  1. 大栈堆用来存放中位数的左半部分和中位数(从小到大排序),小栈堆存放中位数的右半部分(从大到小排序)。每次先放大栈堆,再放小栈堆,可计算两个栈堆的总数为奇为偶判断。
class Solution:
    def __init__(self):
        #存放中位数的左半部分及中位数
        self.max_heap = []
        #存放中位数的右半部分
        self.min_heap = []
    def max_to_min(self,minheap):
        for i in range(len(minheap)-1,0,-1):
            if minheap[i] > minheap[i-1]:
                tmp = minheap[i]
                minheap[i] = minheap[i-1]
                minheap[i-1] = tmp
            else:
                break
        return minheap
    def min_to_max(self,maxheap):
        for i in range(len(maxheap)-1,0,-1):
            if maxheap[i] < maxheap[i-1]:
                tmp = maxheap[i]
                maxheap[i] = maxheap[i-1]
                maxheap[i-1] = tmp
            else:
                break
        return maxheap
    def Insert(self, num):
        l = len(self.max_heap) + len(self.min_heap)
        #偶数,则说明要往大顶堆中加入数,则需要加入的是小顶堆中的最小值
        #先把num加入小顶堆中,排序后,将堆顶元素(最小值)送入到大顶堆中,并对大栈顶排序
        if l % 2 == 0: 
            self.min_heap.append(num)
            self.min_heap = self.max_to_min(self.min_heap)
            self.max_heap.append(self.min_heap.pop(-1))
            self.max_heap = self.min_to_max(self.max_heap)
        #奇数,则说明要往小顶堆中加入数,则需要加入的是大顶堆中的最大值
        #先把num加入大顶堆中,排序后,将堆顶元素(最大值)送入到小顶堆中,并对小栈顶排序
        else:
            self.max_heap.append(num)
            self.max_heap = self.min_to_max(self.max_heap)
            self.min_heap.append(self.max_heap.pop(-1))
            self.min_heap = self.max_to_min(self.min_heap)          
            
        # write code here
    def GetMedian(self):
        l = len(self.max_heap) + len(self.min_heap)
        if l % 2 == 0:
            return (self.max_heap[-1] + self.min_heap[-1]) / 2.0
        else:
            return self.max_heap[-1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值