leetcode 面试题41 数据流中的中位数

解题思路:(1)在添加元素的过程中保持数组的有序,于是把这个问题抽象成插入排序,每次从头遍历查找插入的位置,直接这样导致超时,于是想到将插入的数和中位数作比较,这样每次可以少遍历一半的数据,测试通过

class MedianFinder:

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.data = []
        self.size = 0


    def addNum(self, num: int) -> None:
        if self.size == 0:
            self.data = [num]
            self.size += 1
            return
        if num < self.data[self.size // 2]:
            i = 0
            while(i < self.size // 2 and self.data[i] < num):
                i += 1
        else:
            i = self.size // 2
            while(i < self.size and self.data[i] < num):
                i += 1

        self.data.insert(i, num)
        self.size +=1

    def findMedian(self) -> float:
        return (self.data[self.size // 2] + self.data[(self.size - 1) // 2]) / 2

(2)上面的方法效率依旧不是很高,可以将查找用二分查找代替

class MedianFinder:

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.data = []
        self.size = 0


    def addNum(self, num: int) -> None:
        
        left, right = 0, self.size
        while(left < right):
            mid = left + (right - left) // 2
            if self.data[mid] < num:
                left = mid + 1
            else:
                right = mid

        self.data.insert(left, num)
        self.size +=1

    def findMedian(self) -> float:
        return (self.data[self.size // 2] + self.data[(self.size - 1) // 2]) / 2

(3)上面的方法查找效率得到了提高,但是插入的时间复杂度依旧和数组长度成正比,下面优化插入的时间复杂度,可以用小顶堆来存储一半(n为奇数,存储n//2+1,n为偶数存储n//2)更大的数,用大顶推存储一半(n为奇数,存储n//2-1,n为偶数存储n//2)更小的数。算法流程为:(1)当大顶堆和小顶堆元素一样多时,需要向小顶堆插入元素,将要添加的元素插入大顶堆然后弹出大顶堆的堆顶插入到小顶堆中(2)如果此时元素个数不相等,需要向大顶推插入元素,将要添加的元素插入到小顶堆然后弹出小顶堆的堆顶插入到大顶堆中
(3)去中位数时,两个堆元素个数相等取两个堆的堆顶取平均值,不相等时取小顶堆的堆顶返回

from heapq import *
class MedianFinder:

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.bigger = [] #储存n//2 或者 n//2+1个元素
        self.smaller = [] #储存n//2或者 n//2+1个元素


    def addNum(self, num: int) -> None:
        
        if len(self.bigger) == len(self.smaller):
            heappush(self.bigger, -heappushpop(self.smaller, -num))
        else:
            heappush(self.smaller, -heappushpop(self.bigger, num))

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值