Skip to content

Commit 48e5754

Browse files
committed
feat: solve #289 with python
1 parent c5d1d4d commit 48e5754

File tree

1 file changed

+67
-0
lines changed
  • find-median-from-data-stream

1 file changed

+67
-0
lines changed

find-median-from-data-stream/EGON.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
from heapq import heappush, heappop
2+
from unittest import TestCase, main
3+
4+
5+
class MedianFinder:
6+
"""
7+
Runtime: 137 ms (Beats 56.16%)
8+
Time Complexity:
9+
1) addNum
10+
- 최악의 경우 heappush + (heappop + heappush) + (heappop + heapppush) 가 발생할 수 있으므로 O(5 * log n)
11+
> O(5 * log n) ~= O(log n)
12+
2) findMedian
13+
> heap의 루트 값을 가지고 사칙연산만 하므로 O(1)
14+
15+
Memory: 39.94 MB (Beats 5.85%)
16+
Space Complexity: O(n)
17+
- max_heap은 최대 n // 2 개 혹은 n // 2 + 1개의 원소를 가지므로 O(n / 2 + 1), upper bound
18+
- min_heap은 최대 n // 2개의 원소를 가지므로 O(n / 2)
19+
> O(n / 2 + 1) + O(n / 2) ~= O(n) + O(n) ~= O(n)
20+
"""
21+
22+
def __init__(self):
23+
self.max_heap = []
24+
self.min_heap = []
25+
26+
def addNum(self, num):
27+
heappush(self.max_heap, -num)
28+
if self.min_heap and (-self.max_heap[0] > self.min_heap[0]):
29+
heappush(self.min_heap, -heappop(self.max_heap))
30+
31+
if len(self.max_heap) > len(self.min_heap) + 1:
32+
heappush(self.min_heap, -heappop(self.max_heap))
33+
elif len(self.max_heap) < len(self.min_heap):
34+
heappush(self.max_heap, -heappop(self.min_heap))
35+
36+
def findMedian(self):
37+
if self.max_heap and self.min_heap:
38+
if len(self.max_heap) == len(self.min_heap):
39+
return ((-self.max_heap[0]) + self.min_heap[0]) / 2
40+
else:
41+
return -self.max_heap[0]
42+
elif self.min_heap and not self.max_heap:
43+
return self.min_heap[0]
44+
elif not self.min_heap and self.max_heap:
45+
return -self.max_heap[0]
46+
else:
47+
return 0.0
48+
49+
50+
class _LeetCodeTestCases(TestCase):
51+
52+
def test_1(self):
53+
medianFinder = MedianFinder()
54+
medianFinder.addNum(-1)
55+
self.assertEqual(medianFinder.findMedian(), -1.0)
56+
medianFinder.addNum(-2)
57+
self.assertEqual(medianFinder.findMedian(), -1.5)
58+
medianFinder.addNum(-3)
59+
self.assertEqual(medianFinder.findMedian(), -2.0)
60+
medianFinder.addNum(-4)
61+
self.assertEqual(medianFinder.findMedian(), -2.5)
62+
medianFinder.addNum(-5)
63+
self.assertEqual(medianFinder.findMedian(), -3.0)
64+
65+
66+
if __name__ == '__main__':
67+
main()

0 commit comments

Comments
 (0)