Skip to content

Commit ff7b0b5

Browse files
authored
Merge pull request #1551 from ayosecu/main
[ayosecu] Week 10 Solutions
2 parents be6bba7 + a5687d5 commit ff7b0b5

File tree

5 files changed

+265
-0
lines changed

5 files changed

+265
-0
lines changed

course-schedule/ayosecu.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from typing import List
2+
from collections import defaultdict, deque
3+
4+
class Solution:
5+
"""
6+
- Time Complexity: O(N + P), N = numCourses, P = len(prerequisites)
7+
- Space Complexity: O(N + P)
8+
"""
9+
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
10+
# Topology Sort
11+
# BFS based, ingress count, visited
12+
ingress_cnt = [0] * numCourses
13+
dic = defaultdict(list)
14+
15+
for dst, src in prerequisites:
16+
ingress_cnt[dst] += 1
17+
dic[src].append(dst)
18+
19+
dq = deque([])
20+
for dst in range(numCourses):
21+
if ingress_cnt[dst] == 0:
22+
dq.append(dst)
23+
24+
visited_count = 0
25+
while dq:
26+
src = dq.popleft()
27+
visited_count += 1
28+
29+
for dst in dic[src]:
30+
ingress_cnt[dst] -= 1
31+
if ingress_cnt[dst] == 0:
32+
dq.append(dst)
33+
34+
return visited_count == numCourses
35+
36+
tc = [
37+
(2, [[1,0]], True),
38+
(2, [[1,0],[0,1]], False)
39+
]
40+
41+
sol = Solution()
42+
for i, (n, p, e) in enumerate(tc, 1):
43+
r = sol.canFinish(n, p)
44+
print(f"TC {i} is Passed!" if r == e else f"TC {i} is Failed! - Expected: {e}, Result: {r}")

invert-binary-tree/ayosecu.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
from typing import Optional
2+
3+
class TreeNode:
4+
def __init__(self, val=0, left=None, right=None):
5+
self.val = val
6+
self.left = left
7+
self.right = right
8+
9+
class Solution:
10+
"""
11+
- Time Complexity: O(N), N = The number of nodes
12+
- Space complexity: O(H), H = The height of the tree
13+
"""
14+
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
15+
if not root:
16+
return
17+
18+
root.left, root.right = root.right, root.left
19+
20+
self.invertTree(root.left)
21+
self.invertTree(root.right)
22+
23+
return root
24+
25+
def build_tree(values):
26+
from collections import deque
27+
if not values:
28+
return None
29+
root = TreeNode(values[0])
30+
queue = deque([root])
31+
i = 1
32+
while i < len(values):
33+
node = queue.popleft()
34+
if values[i] is not None:
35+
node.left = TreeNode(values[i])
36+
queue.append(node.left)
37+
i += 1
38+
if i < len(values) and values[i] is not None:
39+
node.right = TreeNode(values[i])
40+
queue.append(node.right)
41+
i += 1
42+
return root
43+
44+
def tree_to_list(root):
45+
from collections import deque
46+
if not root:
47+
return []
48+
result = []
49+
queue = deque([root])
50+
while queue:
51+
node = queue.popleft()
52+
if node:
53+
result.append(node.val)
54+
queue.append(node.left)
55+
queue.append(node.right)
56+
else:
57+
result.append(None)
58+
# Remove trailing None
59+
while result and result[-1] is None:
60+
result.pop()
61+
return result
62+
63+
tc = [
64+
([4,2,7,1,3,6,9], [4,7,2,9,6,3,1]),
65+
([2,1,3], [2,3,1]),
66+
([], [])
67+
]
68+
69+
sol = Solution()
70+
for i, (n, e) in enumerate(tc, 1):
71+
r = tree_to_list(sol.invertTree(build_tree(n)))
72+
print(f"TC {i} is Passed!" if r == e else f"TC {i} is Failed! - Expected: {e}, Result: {r}")

jump-game/ayosecu.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from typing import List
2+
3+
class Solution:
4+
"""
5+
- Time Complexity: O(n), n = len(nums)
6+
- Space Complexity: O(1)
7+
"""
8+
def canJump(self, nums: List[int]) -> bool:
9+
max_jump = 0
10+
for i, jump in enumerate(nums):
11+
if i > max_jump:
12+
return False
13+
max_jump = max(max_jump, i + jump)
14+
return True
15+
16+
tc = [
17+
([2,3,1,1,4], True),
18+
([3,2,1,0,4], False)
19+
]
20+
21+
sol = Solution()
22+
for i, (n, e) in enumerate(tc, 1):
23+
r = sol.canJump(n)
24+
print(f"TC {i} is Passed!" if r == e else f"TC {i} is Failed! - Expected: {e}, Result: {r}")

merge-k-sorted-lists/ayosecu.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
from typing import List, Optional
2+
from heapq import heappush, heappop
3+
4+
# Definition for singly-linked list.
5+
class ListNode:
6+
def __init__(self, val=0, next=None):
7+
self.val = val
8+
self.next = next
9+
10+
class Solution:
11+
"""
12+
- Time Complexity: O(nlogk)
13+
- n = Total number of nodes in lists
14+
- k = The number of linked lists = len(lists)
15+
- Space Complexity: O(k)
16+
- Heap stores at most k elements at any time
17+
"""
18+
def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
19+
heap = []
20+
21+
for i, node in enumerate(lists):
22+
if node:
23+
heappush(heap, (node.val, i, node))
24+
25+
dummy = ListNode(0)
26+
tail = dummy
27+
28+
while heap:
29+
val, i, node = heappop(heap)
30+
tail.next = node
31+
tail = node
32+
if node.next:
33+
heappush(heap, (node.next.val, i, node.next))
34+
35+
return dummy.next
36+
37+
### TC Helpers ###
38+
def build_linked_list(values):
39+
dummy = ListNode(0)
40+
current = dummy
41+
for v in values:
42+
current.next = ListNode(v)
43+
current = current.next
44+
return dummy.next
45+
46+
def linked_list_to_list(node):
47+
result = []
48+
while node:
49+
result.append(node.val)
50+
node = node.next
51+
return result
52+
53+
### DO TEST ###
54+
def do_test():
55+
sol = Solution()
56+
57+
# TC 1
58+
lists = [
59+
build_linked_list([1, 4, 5]),
60+
build_linked_list([1, 3, 4]),
61+
build_linked_list([2, 6])
62+
]
63+
e = [1, 1, 2, 3, 4, 4, 5, 6]
64+
merged = sol.mergeKLists(lists)
65+
r = linked_list_to_list(merged)
66+
print(f"TC 1 is Passed!" if r == e else f"TC 1 is Failed! - Expected: {e}, Result: {r}")
67+
68+
# TC 2
69+
lists = [
70+
build_linked_list([]),
71+
build_linked_list([1]),
72+
build_linked_list([])
73+
]
74+
e = [1]
75+
merged = sol.mergeKLists(lists)
76+
r = linked_list_to_list(merged)
77+
print(f"TC 2 is Passed!" if r == e else f"TC 2 is Failed! - Expected: {e}, Result: {r}")
78+
79+
# TC 3
80+
lists = []
81+
e = []
82+
merged = sol.mergeKLists(lists)
83+
r = linked_list_to_list(merged)
84+
print(f"TC 3 is Passed!" if r == e else f"TC 3 is Failed! - Expected: {e}, Result: {r}")
85+
86+
do_test()
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from typing import List
2+
3+
class Solution:
4+
"""
5+
- Time Complexity: O(logN), N = len(nums)
6+
- Space Complexity: O(1)
7+
"""
8+
def search(self, nums: List[int], target: int) -> int:
9+
left, right = 0, len(nums) - 1
10+
11+
while left <= right:
12+
mid = (left + right) // 2
13+
14+
if target == nums[mid]:
15+
return mid
16+
17+
if nums[left] <= nums[mid]:
18+
if nums[left] <= target < nums[mid]:
19+
right = mid - 1
20+
else:
21+
left = mid + 1
22+
else:
23+
if nums[mid] < target <= nums[right]:
24+
left = mid + 1
25+
else:
26+
right = mid - 1
27+
28+
return -1
29+
30+
tc = [
31+
([4, 5, 6, 7, 0, 1, 2], 0, 4),
32+
([4, 5, 6, 7, 0, 1, 2], 3, -1),
33+
([1], 0, -1)
34+
]
35+
36+
solution = Solution()
37+
for i, (n, t, e) in enumerate(tc, 1):
38+
r = solution.search(n, t)
39+
print(f"TC {i} is Passed!" if r == e else f"TC {i} is Failed! - Expected: {e}, Result: {r}")

0 commit comments

Comments
 (0)