diff --git a/binary-tree-maximum-path-sum/ayosecu.py b/binary-tree-maximum-path-sum/ayosecu.py new file mode 100644 index 000000000..c9aa71e76 --- /dev/null +++ b/binary-tree-maximum-path-sum/ayosecu.py @@ -0,0 +1,54 @@ +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 Tree + """ + def maxPathSum(self, root: Optional[TreeNode]) -> int: + self.max_sum = float("-inf") + + def dfs(node): + if not node: + return 0 + + # Find max sum from the left and right children (more than 0) + l_sum = max(dfs(node.left), 0) + r_sum = max(dfs(node.right), 0) + + # Calculate current sum and update max_sum + current_sum = node.val + l_sum + r_sum + self.max_sum = max(self.max_sum, current_sum) + + # Return larger path + return node.val + max(l_sum, r_sum) + + dfs(root) + + return self.max_sum + +def do_test(): + sol = Solution() + + root1 = TreeNode(1) + root1.left = TreeNode(2) + root1.right = TreeNode(3) + e1 = 6 + r1 = sol.maxPathSum(root1) + print(f"TC 1 is Passed!" if r1 == e1 else f"TC 1 is Failed! - Expected: {e1}, Result: {r1}") + + root2 = TreeNode(-10) + root2.left = TreeNode(9) + root2.right = TreeNode(20) + root2.right.left = TreeNode(15) + root2.right.right = TreeNode(7) + e2 = 42 + r2 = sol.maxPathSum(root2) + print(f"TC 2 is Passed!" if r2 == e2 else f"TC 2 is Failed! - Expected: {e2}, Result: {r2}") + +do_test() diff --git a/graph-valid-tree/ayosecu.py b/graph-valid-tree/ayosecu.py new file mode 100644 index 000000000..9798c0c6e --- /dev/null +++ b/graph-valid-tree/ayosecu.py @@ -0,0 +1,42 @@ +from collections import deque, defaultdict + +class Solution: + """ + - Time Complexity: O(n + e), e = len(edges) + - Space Complexity: O(n), The size of dictionary + """ + def validTree(self, n, edges): + # The number of edges must be "n - 1" + if len(edges) != n - 1: + return False + + dic = defaultdict(list) + for u, v in edges: + dic[u].append(v) + dic[v].append(u) + + # BFS for visiting all nodes + visited = set() + dq = deque([0]) + + while dq: + node = dq.popleft() + if node in visited: + continue + visited.add(node) + for next in dic[node]: + if next not in visited: + dq.append(next) + + # Check all nodes were visited + return len(visited) == n + +tc = [ + (5, [[0, 1], [0, 2], [0, 3], [1, 4]], True), + (5, [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]], False) +] + +sol = Solution() +for i, (n, edges, e) in enumerate(tc, 1): + r = sol.validTree(n, edges) + print(f"TC {i} is Passed!" if r == e else f"TC {i} is Failed! - Expected: {e}, Result: {r}") diff --git a/merge-intervals/ayosecu.py b/merge-intervals/ayosecu.py new file mode 100644 index 000000000..a54055b14 --- /dev/null +++ b/merge-intervals/ayosecu.py @@ -0,0 +1,29 @@ +from typing import List + +class Solution: + """ + - Time complexity: O(nlogn), n = len(intervals) + - Space Complexity: O(1), If output variable excluded. + """ + def merge(self, intervals: List[List[int]]) -> List[List[int]]: + result = [] + intervals.sort(key=lambda x: x[0]) + + for interval in intervals: + if not result or result[-1][1] < interval[0]: + result.append(interval) + else: + result[-1][1] = max(result[-1][1], interval[1]) + + return result + + +tc = [ + ([[1, 3], [2, 6], [8, 10], [15, 18]], [[1, 6], [8, 10], [15, 18]]), + ([[1, 4], [4, 5]], [[1, 5]]) +] + +solution = Solution() +for i, (intervals, e) in enumerate(tc, 1): + r = solution.merge(intervals) + print(f"TC {i} is Passed!" if r == e else f"TC 1 is Failed! - Expected: {e}, Result: {r}") diff --git a/missing-number/ayosecu.py b/missing-number/ayosecu.py new file mode 100644 index 000000000..15d90c905 --- /dev/null +++ b/missing-number/ayosecu.py @@ -0,0 +1,26 @@ +from typing import List + +class Solution: + """ + - Time Complexity: O(n), n = len(nums) + - Space Complexity: O(1) + """ + def missingNumber(self, nums: List[int]) -> int: + n = len(nums) + total = (1 + n) * n // 2 + + for num in nums: + total -= num + + return total + +tc = [ + ([3, 0, 1], 2), + ([0, 1], 2), + ([9, 6, 4, 2, 3, 5, 7, 0, 1], 8) +] + +sol = Solution() +for i, (n, e) in enumerate(tc, 1): + r = sol.missingNumber(n) + print(f"TC {i} is Passed!" if r == e else f"TC {i} is Failed! - Expected: {e}, Result: {r}") diff --git a/reorder-list/ayosecu.py b/reorder-list/ayosecu.py new file mode 100644 index 000000000..cb96e2d6b --- /dev/null +++ b/reorder-list/ayosecu.py @@ -0,0 +1,61 @@ +from typing import Optional +from collections import deque + +class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next + +class Solution: + """ + - Time Complexity: O(N), N = The number of nodes. + - Space Complexity: O(N) + """ + def reorderList(self, head: Optional[ListNode]) -> None: + dq = deque() + + cur = head + while cur: + dq.append(cur) + cur = cur.next + + dummy = ListNode(-1) + cur = dummy + flag = True + while dq: + if flag: + cur.next = dq.popleft() + else: + cur.next = dq.pop() + cur = cur.next + flag = not flag + cur.next = None + + 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(head): + result = [] + while head: + result.append(head.val) + head = head.next + return result + +### TC ### +tc = [ + ([1,2,3,4], [1,4,2,3]), + ([1,2,3,4,5], [1,5,2,4,3]) +] + +sol = Solution() +for i, (l, e) in enumerate(tc, 1): + r = linked_list_to_list(sol.reorderList(build_linked_list(l))) + print(f"TC {i} is Passed!" if r == e else f"TC {i} is Failed! - Expected: {e}, Result: {r}")