295. Find Median from Data Stream
Question: Find Median from Data Stream
Solution1 無腦 sort
python sort: Tim sort: Insertion sort O(n) ~ O(n^2) + Merge sort O(nlogn)
Time Complexity: O(nlogn)
import math
class MedianFinder:
def __init__(self):
self.len_num = 0
self.nums = list()
def addNum(self, num: int) -> None:
self.nums.append(num)
self.len_num += 1
def findMedian(self) -> float:
self.nums.sort()
if self.len_num % 2 == 0:
ind1 = int(self.len_num / 2)
ind2 = ind1 - 1
median = sum(self.nums[ind2: ind1 + 1]) / 2
else:
ind = int(math.floor(self.len_num / 2))
median = self.nums[ind]
return median
Solution2 Max Heap + min Heap
想法:
-
FindMedian: Median 是中間的數字,如果把 sorted list 拆成兩半看,就會是
- 左邊 sorted list 的最大 → max Heap
- 右邊 sorted list 的最小 → min Heap
python 中只有 min Heap,所以左邊的 sorted list 要將 num * -1
當要找出 median 時
- 如果左邊 list 長度 == 右邊 list 長度:return (-left[0] + right[0]) / 2
- 如果左邊 list 長度 > 右邊 list 長度: return -left[0]
超級方便
那麼麻煩的部分就是,在插入數字時 maintain 左右兩邊的 Heap
-
addNum:
- 先看 num 是否比右邊最小的數字大
- 是:加到右邊 list,把右邊 list 最小,換到左邊 list
- 不是:直接加到左邊 list
- 平衡兩邊 list 長度,如果兩邊 list 長度相差大於 1
- heappop 左邊 list 的最小值 * -1,heappush 到右邊 list
Heap maintain Time Complexity: O(logn)
import heapq
class MedianFinder:
def __init__(self):
self.left_nums = list()
self.right_nums = list()
heapq.heapify(self.left_nums)
heapq.heapify(self.right_nums)
def addNum(self, num: int) -> None:
# check num > self.right_nums[0]
if self.right_nums and num > self.right_nums[0]:
heapq.heappush(self.right_nums, num)
ele = heapq.heappop(self.right_nums)
heapq.heappush(self.left_nums, -ele)
else:
heapq.heappush(self.left_nums, -num)
# balance
if len(self.left_nums) - len(self.right_nums) > 1:
ele = heapq.heappop(self.left_nums)
heapq.heappush(self.right_nums, -ele)
def findMedian(self) -> float:
if len(self.left_nums) > len(self.right_nums):
return -self.left_nums[0]
return (-self.left_nums[0] + self.right_nums[0]) / 2
Comments
Post a Comment