栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

数据流中的中位数295(leetcode)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

数据流中的中位数295(leetcode)

数据流的中位数
中位数是有序列表中间的数,如果列表长度是偶数,中位数则是中间两额数的平均值

解法一

用一个大根堆和一个小根堆,小根堆,存放的是最大的一半数,
大根堆 存放的是最小的一半数。 通过堆顶的元素一定能得中位数。

  • 代码实现如下:
class Solution:
    def __init__(self):
        self.minNums = []  # 小根堆,存放是最大的一半的数
        self.maxNums = []  # 大根堆,存放的是最小的一半的数

    def maxHeapInsert(self, num):
        self.maxNums.append(num)
        i = len(self.maxNums) - 1
        while i > 0:
            if self.maxNums[i] > self.maxNums[(i - 1) // 2]:  # 比父节点大就交换
                self.swap(self.maxNums, i, (i - 1) // 2)
                i = (i - 1) // 2
            else:
                break

    def swap(self, arr, i, j):
        """交换两个变量的值"""
        arr[i], arr[j] = arr[j], arr[i]

    def maxHeapPop(self):
        t = self.maxNums[0]  # 返回根节点,大根堆最大值
        self.maxNums[0] = self.maxNums[-1]
        self.maxNums.pop()
        lens = len(self.maxNums)
        i = 0
        while 2 * i + 1 < lens:  # 左孩子的位置,左孩子不越界
            left = 2 * i + 1
            if (left + 1 < lens) and self.maxNums[left + 1] > self.maxNums[left]:  # 左孩子和右孩子较大值的位置。
                left += 1
            if self.maxNums[left] > self.maxNums[i]:  # 左右孩子中较大的值大于当前值
                self.swap(self.maxNums, i, left)  # 当前值和两个孩子中较大的值交换
                i = left
            else:
                break
        return t

    def minHeapInsert(self, num):
        self.minNums.append(num)
        lens = len(self.minNums)
        i = lens - 1
        while i > 0:
            if self.minNums[i] < self.minNums[(i - 1) // 2]:
                self.swap(self.minNums, i, (i - 1) // 2)
                i = (i - 1) // 2
            else:
                break

    def minHeapPop(self):
        t = self.minNums[0]  # 小根堆,堆顶的元素
        self.minNums[0] = self.minNums[-1]
        self.minNums.pop()
        lens = len(self.minNums)
        i = 0
        while 2 * i + 1 < lens:
            left = 2 * i + 1
            if (left + 1 < lens) and self.minNums[left] > self.minNums[left + 1]:
                left += 1 # 取最小值的下标
            if self.minNums[left] < self.minNums[i]: #比当前值小就交换
                self.swap(self.minNums,i,left)
                i = left
            else:
                break
        return t

    def Insert(self, num):
        if len(self.minNums) == len(self.maxNums):
            if len(self.maxNums) > 0 and num < self.maxNums[0]:
                self.maxHeapInsert(num)
                num = self.maxHeapPop()
            self.minHeapInsert(num)
        else:
            if len(self.minNums) > 0 and num > self.minNums[0]:
                self.minHeapInsert(num)
                num=self.minHeapPop()
            self.maxHeapInsert(num)

    def GetMedian(self):
        if len(self.minNums) == len(self.maxNums):
            return (self.maxNums[0] + self.minNums[0]) / 2
        else:
            return self.minNums[0]
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/290751.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号