Skip to content

[Helena] Week 13 #1088

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions find-median-from-data-stream/yolophg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Time Complexity:
# - addNum(): O(log N) - use a heap operation (push/pop) which takes log N time.
# - findMedian(): O(1) - just accessing the top elements of heaps.
# Space Complexity: O(N) - store all elements in two heaps.


class MedianFinder:
def __init__(self):
# max heap (stores the smaller half of numbers, negated values for max heap behavior)
self.maxHeap = []
# min heap (stores the larger half of numbers)
self.minHeap = []

def addNum(self, num: int) -> None:
if not self.maxHeap or num <= -self.maxHeap[0]:
# store as negative to simulate max heap
heapq.heappush(self.maxHeap, -num)
else:
heapq.heappush(self.minHeap, num)

# balance the heaps: maxHeap can have at most 1 more element than minHeap
if len(self.maxHeap) > len(self.minHeap) + 1:
heapq.heappush(self.minHeap, -heapq.heappop(self.maxHeap))
elif len(self.minHeap) > len(self.maxHeap):
heapq.heappush(self.maxHeap, -heapq.heappop(self.minHeap))

def findMedian(self) -> float:
if len(self.maxHeap) > len(self.minHeap):
return -self.maxHeap[0] # odd number of elements, maxHeap has the median
else:
return (-self.maxHeap[0] + self.minHeap[0]) / 2.0 # even case, average of two middle numbers
26 changes: 26 additions & 0 deletions insert-interval/yolophg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Time Complexity: O(N) - iterate through the intervals once.
# Space Complexity: O(N) - store the merged intervals in a new list.

class Solution:
def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]:
output = []
start, end = newInterval

for interval in intervals:
if interval[1] < start:
# no overlap, and the current interval ends before newInterval starts
output.append(interval)
elif interval[0] > end:
# no overlap, and the current interval starts after newInterval ends
output.append([start, end]) # insert merged interval before appending the remaining ones
output.extend(intervals[intervals.index(interval):]) # append remaining intervals
return output
else:
# overlapping case: merge intervals
start = min(start, interval[0])
end = max(end, interval[1])

# add the merged interval at the end if it wasn't added earlier
output.append([start, end])

return output
21 changes: 21 additions & 0 deletions kth-smallest-element-in-a-bst/yolophg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Time Complexity: O(N) - visit each node once in an inorder traversal.
# Space Complexity: O(N) - store all node values in a list.

class Solution:
def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
def inorder(node):
if not node:
return

# go left (smaller values first)
inorder(node.left)
# add the current node's value
values.append(node.val)
# go right (larger values next)
inorder(node.right)

values = []
inorder(root)

# get the k-th smallest element (1-based index)
return values[k - 1]
21 changes: 21 additions & 0 deletions lowest-common-ancestor-of-a-binary-search-tree/yolophg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Time Complexity: O(log N) on average (for balanced BST), worst case O(N) (skewed tree).
# Space Complexity: O(1) - don't use extra space, just a few variables.

class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
# start from the root
node = root

while node:
if p.val > node.val and q.val > node.val:
# both p and q are in the right subtree, so move right
node = node.right
elif p.val < node.val and q.val < node.val:
# both p and q are in the left subtree, so move left
node = node.left
else:
# found the split point where one is on the left and the other is on the right
# or when we reach p or q directly (since a node can be its own ancestor)
return node

return None
19 changes: 19 additions & 0 deletions meeting-rooms/yolophg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Time Complexity: O(N log N) - sorting the intervals takes O(N log N), and the iteration takes O(N).
# Space Complexity: O(1) - sorting is done in place, and we use only a few extra variables.

class Solution:
def can_attend_meetings(intervals):
if not intervals:
return True

# sort intervals based on start times
intervals.sort() # O(N log N) sorting

# check for overlapping meetings
for i in range(len(intervals) - 1):
if intervals[i][1] > intervals[i + 1][0]:
# if the current meeting's end time is later than the next meeting's start time, have a conflict
return False

# no conflicts found, all meetings can be attended
return True