diff --git a/clone-graph/ayosecu.py b/clone-graph/ayosecu.py new file mode 100644 index 000000000..195a94a61 --- /dev/null +++ b/clone-graph/ayosecu.py @@ -0,0 +1,85 @@ +from typing import Optional +from collections import deque + +# Definition for a Node. +class Node: + def __init__(self, val = 0, neighbors = None): + self.val = val + self.neighbors = neighbors if neighbors is not None else [] + +class Solution: + """ + - Time Complexity: O(N + E) + - N = The number of nodes + - E = The number of neighbors + - Space Complexity: O(N + E) + """ + def cloneGraph(self, node: Optional['Node']) -> Optional['Node']: + if not node: + return None + + dq = deque([node]) + dic = {} + dic[node] = Node(node.val) + + while dq: + pop_node = dq.popleft() + + for n in pop_node.neighbors: + if n not in dic: + dq.append(n) + dic[n] = Node(n.val) + dic[pop_node].neighbors.append(dic[n]) + + return dic[node] + + +### TEST CASES ### +def build_graph(adj_list): + if not adj_list: + return None + + nodes = {} + for i in range(1, len(adj_list) + 1): + nodes[i] = Node(i) + + for i, neighbors in enumerate(adj_list, 1): + nodes[i].neighbors = [nodes[n] for n in neighbors] + + return nodes[1] + + +def print_graph(node): + if not node: + print("None") + return + + visited = set() + q = deque([node]) + while q: + curr = q.popleft() + if curr in visited: + continue + visited.add(curr) + print(f"Node {curr.val}: {[n.val for n in curr.neighbors]}") + for neighbor in curr.neighbors: + if neighbor not in visited: + q.append(neighbor) + +tc = [ + [[2,4],[1,3],[2,4],[1,3]], + [[]], + [] +] + +sol = Solution() +for i, adj_list in enumerate(tc, 1): + original = build_graph(adj_list) + print(f"===== TC {i} =====") + print("Original Graph:") + print_graph(original) + + cloned = sol.cloneGraph(original) + + print("\nCloned Graph:") + print_graph(cloned) diff --git a/longest-common-subsequence/ayosecu.py b/longest-common-subsequence/ayosecu.py new file mode 100644 index 000000000..d29965079 --- /dev/null +++ b/longest-common-subsequence/ayosecu.py @@ -0,0 +1,31 @@ +class Solution: + """ + - Time Complexity: O(mn), m = len(text1), n = len(text2) + - Space Complexity: O(mn), The size of the dp variable + """ + def longestCommonSubsequence(self, text1: str, text2: str) -> int: + m, n = len(text1), len(text2) + dp = [ [0] * (n + 1) for _ in range(m + 1) ] + + for i in range(m): + for j in range(n): + if text1[i] == text2[j]: + # if matched, increase length + dp[i + 1][j + 1] = dp[i][j] + 1 + else: + # if unmatched, select a larger length from left and up position + dp[i + 1][j + 1] = max(dp[i + 1][j], dp[i][j + 1]) + + return dp[m][n] + + +tc = [ + ("abcde", "ace", 3), + ("abc", "abc", 3), + ("abc", "def", 0) +] + +sol = Solution() +for i, (s1, s2, e) in enumerate(tc, 1): + r = sol.longestCommonSubsequence(s1, s2) + print(f"TC {i} is Passed!" if r == e else f"TC {i} is Failed! - Expected: {e}, Result: {r}") diff --git a/longest-repeating-character-replacement/ayosecu.py b/longest-repeating-character-replacement/ayosecu.py new file mode 100644 index 000000000..4b3dd5275 --- /dev/null +++ b/longest-repeating-character-replacement/ayosecu.py @@ -0,0 +1,37 @@ +class Solution: + """ + - Time Complexity: O(n), n = len(s) + - Space Complexity: O(1) + """ + def characterReplacement(self, s: str, k: int) -> int: + cnt_arr = [0] * 26 + max_cnt, max_len = 0, 0 + + # Two pointers: left/right + l = 0 + for r in range(len(s)): + # Increase count and find max count by right pointer's alphabet + idx = ord(s[r]) - ord("A") + cnt_arr[idx] += 1 + max_cnt = max(max_cnt, cnt_arr[idx]) + + # Left pointer moves if changable characters exceed k + if (r - l + 1) - max_cnt > k: + idx = ord(s[l]) - ord("A") + cnt_arr[idx] -= 1 + l += 1 + + # Update the max length + max_len = max(max_len, r - l + 1) + + return max_len + +tc = [ + ("ABAB", 2, 4), + ("AABABBA", 1, 4) +] + +sol = Solution() +for i, (s, k, e) in enumerate(tc, 1): + r = sol.characterReplacement(s, k) + print(f"TC {i} is Passed!" if r == e else f"TC {i} is Failed! - Expected: {e}, Result: {r}") diff --git a/palindromic-substrings/ayosecu.py b/palindromic-substrings/ayosecu.py new file mode 100644 index 000000000..3251f12bf --- /dev/null +++ b/palindromic-substrings/ayosecu.py @@ -0,0 +1,31 @@ +class Solution: + """ + - Time Complexity: O(n^2), n = len(s) + - Space Complexity: O(1) + """ + def countSubstrings(self, s: str) -> int: + count = 0 + + def checkSide(l, r): + cnt = 0 + while l >= 0 and r < len(s) and s[l] == s[r]: + cnt += 1 + l -= 1 + r += 1 + return cnt + + for i in range(len(s)): + count += checkSide(i, i) # Odd case + count += checkSide(i, i + 1) # Even case + + return count + +tc = [ + ("abc", 3), + ("aaa", 6) +] + +sol = Solution() +for i, (s, e) in enumerate(tc, 1): + r = sol.countSubstrings(s) + print(f"TC {i} is Passed!" if r == e else f"TC {i} is Failed! - Expected: {e}, Result: {r}") diff --git a/reverse-bits/ayosecu.py b/reverse-bits/ayosecu.py new file mode 100644 index 000000000..3db8c02da --- /dev/null +++ b/reverse-bits/ayosecu.py @@ -0,0 +1,24 @@ +class Solution: + """ + - Time Complexity: O(1), 32 times calculation + - Space Complexity: O(1) + """ + def reverseBits(self, n: int) -> int: + result = 0 + + for _ in range(32): + result <<= 1 + result |= n & 1 + n >>= 1 + + return result + +tc = [ + (43261596, 964176192), + (4294967293, 3221225471) +] + +sol = Solution() +for i, (n, e) in enumerate(tc, 1): + r = sol.reverseBits(n) + print(f"TC {i} is Passed!" if r == e else f"TC {i} is Failed! - Expected: {e}, Result: {r}")