From eca856ccd3b8b08448ba77c11c4e5c7f99a90b48 Mon Sep 17 00:00:00 2001 From: AYo Secu Date: Mon, 2 Jun 2025 13:19:40 -0700 Subject: [PATCH 1/5] - Invert Binary Tree #226 --- invert-binary-tree/ayosecu.py | 72 +++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 invert-binary-tree/ayosecu.py diff --git a/invert-binary-tree/ayosecu.py b/invert-binary-tree/ayosecu.py new file mode 100644 index 000000000..1bd6714bb --- /dev/null +++ b/invert-binary-tree/ayosecu.py @@ -0,0 +1,72 @@ +from typing import Optional + +class TreeNode: + def __init__(self, val=0, left=None, right=None): + self.val = val + self.left = left + self.right = right + +class Solution: + """ + - Time Complexity: O(N), N = The number of nodes + - Space complexity: O(H), H = The height of the tree + """ + def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]: + if not root: + return + + root.left, root.right = root.right, root.left + + self.invertTree(root.left) + self.invertTree(root.right) + + return root + +def build_tree(values): + from collections import deque + if not values: + return None + root = TreeNode(values[0]) + queue = deque([root]) + i = 1 + while i < len(values): + node = queue.popleft() + if values[i] is not None: + node.left = TreeNode(values[i]) + queue.append(node.left) + i += 1 + if i < len(values) and values[i] is not None: + node.right = TreeNode(values[i]) + queue.append(node.right) + i += 1 + return root + +def tree_to_list(root): + from collections import deque + if not root: + return [] + result = [] + queue = deque([root]) + while queue: + node = queue.popleft() + if node: + result.append(node.val) + queue.append(node.left) + queue.append(node.right) + else: + result.append(None) + # Remove trailing None + while result and result[-1] is None: + result.pop() + return result + +tc = [ + ([4,2,7,1,3,6,9], [4,7,2,9,6,3,1]), + ([2,1,3], [2,3,1]), + ([], []) +] + +sol = Solution() +for i, (n, e) in enumerate(tc, 1): + r = tree_to_list(sol.invertTree(build_tree(n))) + print(f"TC {i} is Passed!" if r == e else f"TC {i} is Failed! - Expected: {e}, Result: {r}") From 0a48b729eb9fe3aa1c81f51efe435ac3139ae84b Mon Sep 17 00:00:00 2001 From: AYo Secu Date: Tue, 3 Jun 2025 17:10:20 -0700 Subject: [PATCH 2/5] - Search In Rotated Sorted Array #246 --- search-in-rotated-sorted-array/ayosecu.py | 39 +++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 search-in-rotated-sorted-array/ayosecu.py diff --git a/search-in-rotated-sorted-array/ayosecu.py b/search-in-rotated-sorted-array/ayosecu.py new file mode 100644 index 000000000..62751911a --- /dev/null +++ b/search-in-rotated-sorted-array/ayosecu.py @@ -0,0 +1,39 @@ +from typing import List + +class Solution: + """ + - Time Complexity: O(logN), N = len(nums) + - Space Complexity: O(1) + """ + def search(self, nums: List[int], target: int) -> int: + left, right = 0, len(nums) - 1 + + while left <= right: + mid = (left + right) // 2 + + if target == nums[mid]: + return mid + + if nums[left] <= nums[mid]: + if nums[left] <= target < nums[mid]: + right = mid - 1 + else: + left = mid + 1 + else: + if nums[mid] < target <= nums[right]: + left = mid + 1 + else: + right = mid - 1 + + return -1 + +tc = [ + ([4, 5, 6, 7, 0, 1, 2], 0, 4), + ([4, 5, 6, 7, 0, 1, 2], 3, -1), + ([1], 0, -1) +] + +solution = Solution() +for i, (n, t, e) in enumerate(tc, 1): + r = solution.search(n, t) + print(f"TC {i} is Passed!" if r == e else f"TC {i} is Failed! - Expected: {e}, Result: {r}") From 7d751353c0f8e0f64b3d99228975965a4929a46e Mon Sep 17 00:00:00 2001 From: AYo Secu Date: Fri, 6 Jun 2025 13:51:32 -0700 Subject: [PATCH 3/5] - Course Schedule #261 --- course-schedule/ayosecu.py | 44 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 course-schedule/ayosecu.py diff --git a/course-schedule/ayosecu.py b/course-schedule/ayosecu.py new file mode 100644 index 000000000..2ecdd1e9b --- /dev/null +++ b/course-schedule/ayosecu.py @@ -0,0 +1,44 @@ +from typing import List +from collections import defaultdict, deque + +class Solution: + """ + - Time Complexity: O(N + P), N = numCourses, P = len(prerequisites) + - Space Complexity: O(N + P) + """ + def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool: + # Topology Sort + # BFS based, ingress count, visited + ingress_cnt = [0] * numCourses + dic = defaultdict(list) + + for dst, src in prerequisites: + ingress_cnt[dst] += 1 + dic[src].append(dst) + + dq = deque([]) + for dst in range(numCourses): + if ingress_cnt[dst] == 0: + dq.append(dst) + + visited_count = 0 + while dq: + src = dq.popleft() + visited_count += 1 + + for dst in dic[src]: + ingress_cnt[dst] -= 1 + if ingress_cnt[dst] == 0: + dq.append(dst) + + return visited_count == numCourses + +tc = [ + (2, [[1,0]], True), + (2, [[1,0],[0,1]], False) +] + +sol = Solution() +for i, (n, p, e) in enumerate(tc, 1): + r = sol.canFinish(n, p) + print(f"TC {i} is Passed!" if r == e else f"TC {i} is Failed! - Expected: {e}, Result: {r}") From e23f7f41f07f3a1a8f870c5fdf55b92767d2c2d9 Mon Sep 17 00:00:00 2001 From: AYo Secu Date: Fri, 6 Jun 2025 14:49:00 -0700 Subject: [PATCH 4/5] - Jump Game #276 --- jump-game/ayosecu.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 jump-game/ayosecu.py diff --git a/jump-game/ayosecu.py b/jump-game/ayosecu.py new file mode 100644 index 000000000..c7c0cd8d3 --- /dev/null +++ b/jump-game/ayosecu.py @@ -0,0 +1,24 @@ +from typing import List + +class Solution: + """ + - Time Complexity: O(n), n = len(nums) + - Space Complexity: O(1) + """ + def canJump(self, nums: List[int]) -> bool: + max_jump = 0 + for i, jump in enumerate(nums): + if i > max_jump: + return False + max_jump = max(max_jump, i + jump) + return True + +tc = [ + ([2,3,1,1,4], True), + ([3,2,1,0,4], False) +] + +sol = Solution() +for i, (n, e) in enumerate(tc, 1): + r = sol.canJump(n) + print(f"TC {i} is Passed!" if r == e else f"TC {i} is Failed! - Expected: {e}, Result: {r}") From a5687d5c263e799ee6c4f473047a7ec8601fbdda Mon Sep 17 00:00:00 2001 From: AYo Secu Date: Fri, 6 Jun 2025 23:57:08 -0700 Subject: [PATCH 5/5] - Merge K Sorted Lists #286 --- merge-k-sorted-lists/ayosecu.py | 86 +++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 merge-k-sorted-lists/ayosecu.py diff --git a/merge-k-sorted-lists/ayosecu.py b/merge-k-sorted-lists/ayosecu.py new file mode 100644 index 000000000..57ff8e7d1 --- /dev/null +++ b/merge-k-sorted-lists/ayosecu.py @@ -0,0 +1,86 @@ +from typing import List, Optional +from heapq import heappush, heappop + +# Definition for singly-linked list. +class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next + +class Solution: + """ + - Time Complexity: O(nlogk) + - n = Total number of nodes in lists + - k = The number of linked lists = len(lists) + - Space Complexity: O(k) + - Heap stores at most k elements at any time + """ + def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]: + heap = [] + + for i, node in enumerate(lists): + if node: + heappush(heap, (node.val, i, node)) + + dummy = ListNode(0) + tail = dummy + + while heap: + val, i, node = heappop(heap) + tail.next = node + tail = node + if node.next: + heappush(heap, (node.next.val, i, node.next)) + + return dummy.next + +### TC Helpers ### +def build_linked_list(values): + dummy = ListNode(0) + current = dummy + for v in values: + current.next = ListNode(v) + current = current.next + return dummy.next + +def linked_list_to_list(node): + result = [] + while node: + result.append(node.val) + node = node.next + return result + +### DO TEST ### +def do_test(): + sol = Solution() + + # TC 1 + lists = [ + build_linked_list([1, 4, 5]), + build_linked_list([1, 3, 4]), + build_linked_list([2, 6]) + ] + e = [1, 1, 2, 3, 4, 4, 5, 6] + merged = sol.mergeKLists(lists) + r = linked_list_to_list(merged) + print(f"TC 1 is Passed!" if r == e else f"TC 1 is Failed! - Expected: {e}, Result: {r}") + + # TC 2 + lists = [ + build_linked_list([]), + build_linked_list([1]), + build_linked_list([]) + ] + e = [1] + merged = sol.mergeKLists(lists) + r = linked_list_to_list(merged) + print(f"TC 2 is Passed!" if r == e else f"TC 2 is Failed! - Expected: {e}, Result: {r}") + + # TC 3 + lists = [] + e = [] + merged = sol.mergeKLists(lists) + r = linked_list_to_list(merged) + print(f"TC 3 is Passed!" if r == e else f"TC 3 is Failed! - Expected: {e}, Result: {r}") + +do_test()