Skip to content

Commit e10ec05

Browse files
authored
Merge pull request #1088 from yolophg/main
[Helena] Week 13
2 parents a672fcd + 8d3a5b0 commit e10ec05

File tree

5 files changed

+118
-0
lines changed

5 files changed

+118
-0
lines changed
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Time Complexity:
2+
# - addNum(): O(log N) - use a heap operation (push/pop) which takes log N time.
3+
# - findMedian(): O(1) - just accessing the top elements of heaps.
4+
# Space Complexity: O(N) - store all elements in two heaps.
5+
6+
7+
class MedianFinder:
8+
def __init__(self):
9+
# max heap (stores the smaller half of numbers, negated values for max heap behavior)
10+
self.maxHeap = []
11+
# min heap (stores the larger half of numbers)
12+
self.minHeap = []
13+
14+
def addNum(self, num: int) -> None:
15+
if not self.maxHeap or num <= -self.maxHeap[0]:
16+
# store as negative to simulate max heap
17+
heapq.heappush(self.maxHeap, -num)
18+
else:
19+
heapq.heappush(self.minHeap, num)
20+
21+
# balance the heaps: maxHeap can have at most 1 more element than minHeap
22+
if len(self.maxHeap) > len(self.minHeap) + 1:
23+
heapq.heappush(self.minHeap, -heapq.heappop(self.maxHeap))
24+
elif len(self.minHeap) > len(self.maxHeap):
25+
heapq.heappush(self.maxHeap, -heapq.heappop(self.minHeap))
26+
27+
def findMedian(self) -> float:
28+
if len(self.maxHeap) > len(self.minHeap):
29+
return -self.maxHeap[0] # odd number of elements, maxHeap has the median
30+
else:
31+
return (-self.maxHeap[0] + self.minHeap[0]) / 2.0 # even case, average of two middle numbers

insert-interval/yolophg.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Time Complexity: O(N) - iterate through the intervals once.
2+
# Space Complexity: O(N) - store the merged intervals in a new list.
3+
4+
class Solution:
5+
def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]:
6+
output = []
7+
start, end = newInterval
8+
9+
for interval in intervals:
10+
if interval[1] < start:
11+
# no overlap, and the current interval ends before newInterval starts
12+
output.append(interval)
13+
elif interval[0] > end:
14+
# no overlap, and the current interval starts after newInterval ends
15+
output.append([start, end]) # insert merged interval before appending the remaining ones
16+
output.extend(intervals[intervals.index(interval):]) # append remaining intervals
17+
return output
18+
else:
19+
# overlapping case: merge intervals
20+
start = min(start, interval[0])
21+
end = max(end, interval[1])
22+
23+
# add the merged interval at the end if it wasn't added earlier
24+
output.append([start, end])
25+
26+
return output
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Time Complexity: O(N) - visit each node once in an inorder traversal.
2+
# Space Complexity: O(N) - store all node values in a list.
3+
4+
class Solution:
5+
def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
6+
def inorder(node):
7+
if not node:
8+
return
9+
10+
# go left (smaller values first)
11+
inorder(node.left)
12+
# add the current node's value
13+
values.append(node.val)
14+
# go right (larger values next)
15+
inorder(node.right)
16+
17+
values = []
18+
inorder(root)
19+
20+
# get the k-th smallest element (1-based index)
21+
return values[k - 1]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Time Complexity: O(log N) on average (for balanced BST), worst case O(N) (skewed tree).
2+
# Space Complexity: O(1) - don't use extra space, just a few variables.
3+
4+
class Solution:
5+
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
6+
# start from the root
7+
node = root
8+
9+
while node:
10+
if p.val > node.val and q.val > node.val:
11+
# both p and q are in the right subtree, so move right
12+
node = node.right
13+
elif p.val < node.val and q.val < node.val:
14+
# both p and q are in the left subtree, so move left
15+
node = node.left
16+
else:
17+
# found the split point where one is on the left and the other is on the right
18+
# or when we reach p or q directly (since a node can be its own ancestor)
19+
return node
20+
21+
return None

meeting-rooms/yolophg.py

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Time Complexity: O(N log N) - sorting the intervals takes O(N log N), and the iteration takes O(N).
2+
# Space Complexity: O(1) - sorting is done in place, and we use only a few extra variables.
3+
4+
class Solution:
5+
def can_attend_meetings(intervals):
6+
if not intervals:
7+
return True
8+
9+
# sort intervals based on start times
10+
intervals.sort() # O(N log N) sorting
11+
12+
# check for overlapping meetings
13+
for i in range(len(intervals) - 1):
14+
if intervals[i][1] > intervals[i + 1][0]:
15+
# if the current meeting's end time is later than the next meeting's start time, have a conflict
16+
return False
17+
18+
# no conflicts found, all meetings can be attended
19+
return True

0 commit comments

Comments
 (0)