思路一
建立一个大根堆和一个小根堆,然后像两个堆添加数据,规则为:第一个数据总是放在大根堆里,对于任一数据,如果小于等于大根堆堆顶值,则放入大根堆,否则放入小根堆,要注意的是,每添加一个元素都要比较两个堆的size,如果一个的size比另一个的size多2,则需要把size较大堆的堆顶元素弹出,并放入size较小的堆。添加数据完成后,比较两堆的size,如果都为0,返回None;size相同,返回两堆堆顶元素/2;否则返回size大的那个堆的堆顶元素,力扣上高效通过
class MedianFinder:
import heapq
import math
def __init__(self):
"""
initialize your data structure here.
"""
self.maxheap = []
self.minheap = []
def addNum(self, num: int) -> None:
#第一个数或者小于大根堆堆顶元素,就放到大根堆里,否则放到小根堆
if self.maxheap == [] or num <= -self.maxheap[0]:
heapq.heappush(self.maxheap,-num)
else:
heapq.heappush(self.minheap,num)
if len(self.maxheap) == len(self.minheap)-2: #小根堆size大
heapq.heappush(self.maxheap,-heapq.heappop(self.minheap))
if len(self.minheap) == len(self.maxheap)-2: #大根堆size大
heapq.heappush(self.minheap,-heapq.heappop(self.maxheap))
def findMedian(self) -> float:
if len(self.maxheap) + len(self.minheap) == 0:
return None
if len(self.maxheap) == len(self.minheap):
return (-self.maxheap[0] + self.minheap[0]) / 2
else:
return -self.maxheap[0] if len(self.maxheap) > len(self.minheap) else self.minheap[0]
思路二
巧妙利用heapq的nlargest和nsmallest方法,用math.ceil取数组的中心长度K,并根据这个数分别取TopK和BottomK的最后一位,相加除2,这样就不用判断奇偶。但是时间复杂度要高很多,leetcode上超出时限
class MedianFinder:
import heapq
import math
def __init__(self):
"""
initialize your data structure here.
"""
self.s = []
def addNum(self, num: int) -> None:
heapq.heappush(self.s,num)
def findMedian(self) -> float:
K = math.ceil(len(self.s)/2) #math.ceil是往大了取
return (heapq.nlargest(K,self.s)[-1] + heapq.nsmallest(K,self.s)[-1]) / 2
思路三
最原始的笨方法,牛客网上可以通过
class Solution:
def __init__(self):
self.s = []
def Insert(self, num):
# write code here
self.s.append(num)
def GetMedian(self,s):
# write code here
self.s.sort()
length = len(self.s)
if not self.s or length <= 0:
return
if length%2 == 0:
return (self.s[length//2-1]+self.s[length//2])/2.0 #####要除以2.0,而不是2
else:
return self.s[int(length//2)]