[leetcode295]Find Median from Data Stream

问题描述:

Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.

Examples:
[2,3,4] , the median is 3

[2,3], the median is (2 + 3) / 2 = 2.5

Design a data structure that supports the following two operations:

void addNum(int num) - Add a integer number from the data stream to the data structure.
double findMedian() - Return the median of all elements so far.
For example:

add(1)
add(2)
findMedian() -> 1.5
add(3)
findMedian() -> 2

算法:

  1. 用list存储,每次add,直接用append进行。O(1)
    在findMedian中,直接进行list.sort(),返回中间值。
    在findMedian的算法中,时间复杂度为O(n*logn)。
    整个算法复杂度为O(k + t*nlogn)=O(n*logn)结果超时。k为调用add次数,t为调用findMedian次数。
  2. 在add的时候进行二叉搜索,确定插入位置,使用list.insert()进行插入。一次add的时间复杂度为O(logn + n)。
    在findMedian中,直接返回中间值。O(1)
    这个算法的复杂度为O(k *logn +k* n+t)=O(n)结果Accepted。k为调用add次数,t为调用findMedian次数。
  3. 还有更快的算法吗?
    答案是,还有。。。
    分析题目所求结果,其与有序数组的中间两个元素相关,可惜这两个元素在数组中间。。。是的,在中间!有没有办法把数组劈开使中间的两个元素暴露出来,并且这两个元素分别是左半个数组的最大值,是右半个数组的最小值。对,这正是大小堆结构。
    这样,add函数的时间复杂度为O(logn),findMedian的时间复杂度为O(1).整个算法的时间复杂度为O(logn)。
class MedianFinder:
    """ Time Limit Exceeded """
    def __init__(self):
        """ Initialize your data structure here. """
        self.data = []

    def addNum(self, num):
        """ Adds a num into the data structure. :type num: int :rtype: void """
        self.data.append(num)

    def findMedian(self):
        """ Returns the median of current data stream :rtype: float """
        length = len(self.data)
        self.data.sort()
        if length % 2 == 0:
            return (self.data[length//2] + self.data[length//2-1])*0.5
        else:
            return self.data[length//2]*1.0


import bisect

class MedianFinder:
    """ Accepted """
    def __init__(self):
        """ Initialize your data structure here. """
        self.data = []

    def addNum(self, num):
        """ Adds a num into the data structure. :type num: int :rtype: void """
        bisect.insort(self.data, num)

    def findMedian(self):
        """ Returns the median of current data stream :rtype: float """
        length = len(self.data)
        if length % 2 == 0:
            return (self.data[length//2] + self.data[length//2-1])*0.5
        else:
            return self.data[length//2]*1.0


import heapq

class MedianFinder:
    """ heap implement """
    def __init__(self):
        """ Initialize your data structure here. """
        self.left = []
        self.right = []

    def addNum(self, num):
        """ Adds a num into the data structure. :type num: int :rtype: void """
        if len(self.left) == len(self.right):
            heapq.heappush(self.left, -heapq.heappushpop(self.right, num))
        else:
            heapq.heappush(self.right, -heapq.heappushpop(self.left, -num))


    def findMedian(self):
        """ Returns the median of current data stream :rtype: float """
        length = len(self.left) + len(self.right)
        if length%2 == 0:
            left = -self.left[0]
            right = self.right[0]
            return 0.5*(left+right)
        else:
            return -self.left[0]*1.0
全部评论

相关推荐

不愿透露姓名的神秘牛友
07-04 14:35
点赞 评论 收藏
分享
迟缓的斜杠青年巴比Q...:简历被投过的公司卖出去了,我前两天遇到过更离谱的,打电话来问我有没有意向报班学Java学习,服了,还拿我学校一个学长在他们那报班学了之后干了华为OD当招牌
点赞 评论 收藏
分享
兄弟们,实习都是在接各种api,该怎么包装简历
仁者伍敌:感觉我自己做小项目也是各种api啊,我要怎么包装简历
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务