295 Find Median from Data Stream
addNum(1)
addNum(2)
findMedian() -> 1.5
addNum(3)
findMedian() -> 2from queue import PriorityQueue
class myPriorityQueue(PriorityQueue):
def __init__(self):
super(PriorityQueue, self).__init__()
def front(self):
if self.empty():
raise IndexError('Priority Queue is empty')
return self.queue[0]
class MaxPriorityQueue(PriorityQueue):
def __init__(self):
super(PriorityQueue, self).__init__()
def put(self, item, block=True, timeout=None):
super().put(-item)
def get(self, block=True, timeout=None):
return -super().get()
def front(self):
if self.empty():
raise IndexError('Priority Queue is empty')
return -self.queue[0]
class MedianFinder:
def __init__(self):
"""
initialize your data structure here.
"""
self.large_half = myPriorityQueue()
self.small_half = MaxPriorityQueue()
def addNum(self, num):
"""
:type num: int
:rtype: void
"""
if not self.small_half.empty() and not self.large_half.empty():
# if the sizes are the same, then put the number to the group is belongs to
if self.small_half.qsize() == self.large_half.qsize():
# swap the elements if they are in the incorrect group
if self.small_half.front() > self.large_half.front():
self.small_half.put(self.large_half.get())
self.large_half.put(self.small_half.get())
if num > self.small_half.front():
self.large_half.put(num)
else:
self.small_half.put(num)
else:
# if the larger half has more elements than smaller half
if self.small_half.qsize() < self.large_half.qsize():
# if the number belongs in the larger half, we need to trade elements with the smaller half
if num > self.small_half.front():
self.small_half.put(self.large_half.get())
self.large_half.put(num)
else:
self.small_half.put(num)
# otherwise the logic gets reversed. there are more elements in the smaller half
else:
# which means that if the number belongs in the larger half, we are free to put it
# in to make both equal size
if num > self.small_half.front():
self.large_half.put(num)
# otherwise the number belong to smaller half, which means were going to have to trade elements
else:
self.large_half.put(self.small_half.get())
self.small_half.put(num)
else:
self.small_half.put(num) if self.small_half.empty() \
else self.large_half.put(num)
def findMedian(self):
"""
:rtype: float
"""
if self.large_half.qsize() > self.small_half.qsize():
return self.large_half.front()
elif self.large_half.qsize() == self.small_half.qsize():
return (self.large_half.front() +
(self.small_half.front())) / 2
else:
return self.small_half.front()Last updated
