From 2cefe92436bbece83920a819c63034c8146dbf81 Mon Sep 17 00:00:00 2001 From: Dusuna <94776135+dusunax@users.noreply.github.com> Date: Tue, 21 Jan 2025 15:00:31 +0900 Subject: [PATCH 1/6] add solution: reverse-linked-list --- reverse-linked-list/dusunax.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 reverse-linked-list/dusunax.py diff --git a/reverse-linked-list/dusunax.py b/reverse-linked-list/dusunax.py new file mode 100644 index 000000000..569cde36c --- /dev/null +++ b/reverse-linked-list/dusunax.py @@ -0,0 +1,24 @@ +''' +# 206. Reverse Linked List + +iterate through the linked list and reverse the direction of the pointers. + +## Time and Space Complexity + +``` +TC: O(n) +SC: O(1) +``` +''' +class Solution: + def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: + prev = None + current = head + + while current is not None: # TC: O(n) + next_list_temp = current.next + current.next = prev + prev = current + current = next_list_temp + + return prev From ef65d612f74ed8891418eee8b21ab24af04330de Mon Sep 17 00:00:00 2001 From: Dusuna <94776135+dusunax@users.noreply.github.com> Date: Tue, 21 Jan 2025 22:01:53 +0900 Subject: [PATCH 2/6] add solution: longest-substring-without-repeating-characters --- .../dusunax.py | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 longest-substring-without-repeating-characters/dusunax.py diff --git a/longest-substring-without-repeating-characters/dusunax.py b/longest-substring-without-repeating-characters/dusunax.py new file mode 100644 index 000000000..15911ea07 --- /dev/null +++ b/longest-substring-without-repeating-characters/dusunax.py @@ -0,0 +1,35 @@ +''' +# 3. Longest Substring Without Repeating Characters + +use a set to store the characters in the current substring. + + +## Time and Space Complexity + +``` +TC: O(n) +SC: O(n) +``` + +#### TC is O(n): +- iterating with end pointer through the string once. = O(n) +- inner while loop runs at most once for each character in the string. = Amortized O(1) + +#### SC is O(n): +- using a set to store the characters in the current substring. = O(n) + +''' +class Solution: + def lengthOfLongestSubstring(self, s: str) -> int: + max_count = 0 + start = 0 + substrings = set() # SC: O(n) + + for end in range(len(s)): # TC: O(n) + while s[end] in substrings: # TC: Amortized O(1) + substrings.remove(s[start]) + start += 1 + substrings.add(s[end]) + max_count = max(max_count, end - start + 1) + + return max_count From e2941b125d7b55499413bef6c3e24f43027c2d9f Mon Sep 17 00:00:00 2001 From: Dusuna <94776135+dusunax@users.noreply.github.com> Date: Fri, 24 Jan 2025 01:41:09 +0900 Subject: [PATCH 3/6] update solution: longest-substring-without-repeating-characters --- .../dusunax.py | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/longest-substring-without-repeating-characters/dusunax.py b/longest-substring-without-repeating-characters/dusunax.py index 15911ea07..d11cbd638 100644 --- a/longest-substring-without-repeating-characters/dusunax.py +++ b/longest-substring-without-repeating-characters/dusunax.py @@ -6,21 +6,36 @@ ## Time and Space Complexity +### Solution 1: using set + ``` TC: O(n) SC: O(n) ``` -#### TC is O(n): +#### TC is O(n): - iterating with end pointer through the string once. = O(n) - inner while loop runs at most once for each character in the string. = Amortized O(1) #### SC is O(n): - using a set to store the characters in the current substring. = O(n) +### Solution 2: using ASCII array + +``` +TC: O(n) +SC: O(128) +``` + +#### TC is O(n): +- iterating with end pointer through the string once. = O(n) +- checking if the character is in the current substring. + +#### SC is O(1): +- using an array to store the characters in the current substring. = constant space O(128) ''' class Solution: - def lengthOfLongestSubstring(self, s: str) -> int: + def lengthOfLongestSubstringWithSet(self, s: str) -> int: max_count = 0 start = 0 substrings = set() # SC: O(n) @@ -33,3 +48,16 @@ def lengthOfLongestSubstring(self, s: str) -> int: max_count = max(max_count, end - start + 1) return max_count + + def lengthOfLongestSubstring(self, s: str) -> int: + max_count = 0 + start = 0 + char_index = [-1] * 128 # SC: O(128) + + for end in range(len(s)): # TC: O(n) + if char_index[ord(s[end])] >= start: + start = char_index[ord(s[end])] + 1 + char_index[ord(s[end])] = end + max_count = max(max_count, end - start + 1) + + return max_count From 551746a3f774f0f0359fae57e69e6dffac707dd3 Mon Sep 17 00:00:00 2001 From: Dusuna <94776135+dusunax@users.noreply.github.com> Date: Fri, 24 Jan 2025 23:06:27 +0900 Subject: [PATCH 4/6] add solution: number-of-islands --- number-of-islands/dusunax.py | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 number-of-islands/dusunax.py diff --git a/number-of-islands/dusunax.py b/number-of-islands/dusunax.py new file mode 100644 index 000000000..6a8d80ede --- /dev/null +++ b/number-of-islands/dusunax.py @@ -0,0 +1,38 @@ +''' +# 200. Number of Islands + +use DFS to find the number of islands (to find the all the possible cases) + +## Time and Space Complexity + +``` +TC: O(m * n) +SC: O(m * n) +``` + +### TC is O(m * n): +- dfs function is called for each cell in the grid for checking is the land ("1") = O(m * n) + +### SC is O(m * n): +- using a recursive function, the call stack can go as deep as the number of cells in the grid in the worst case. = O(m * n) +''' +class Solution: + def numIslands(self, grid: List[List[str]]) -> int: + def dfs(x, y): + if x < 0 or y < 0 or y >= len(grid) or x >= len(grid[0]) or grid[y][x] == "0" : + return + + grid[y][x] = "0" + dfs(x, y + 1) + dfs(x - 1, y) + dfs(x, y - 1) + dfs(x + 1, y) + + island_count = 0 + for y in range(len(grid)): + for x in range(len(grid[0])): + if grid[y][x] == "1": + dfs(x, y) + island_count += 1 + + return island_count From 6dca22b0593a980f235b99096770df2b85ac6986 Mon Sep 17 00:00:00 2001 From: Dusuna <94776135+dusunax@users.noreply.github.com> Date: Fri, 24 Jan 2025 23:47:59 +0900 Subject: [PATCH 5/6] add solution: unique-paths --- unique-paths/dusunax.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 unique-paths/dusunax.py diff --git a/unique-paths/dusunax.py b/unique-paths/dusunax.py new file mode 100644 index 000000000..dac03df5f --- /dev/null +++ b/unique-paths/dusunax.py @@ -0,0 +1,21 @@ +''' +# 62. Unique Paths + +use dynamic programming & a dp table to store the number of ways to reach each cell. + +### TC is O(m * n): +- iterating through every cell in the grid. = O(m * n) +- updating each cell in the grid. = O(1) + +### SC is O(m * n): +- using a dp table (2D array) to store the number of ways to reach each cell. = O(m * n) +''' +class Solution: + def uniquePaths(self, m: int, n: int) -> int: + dp = [[1] * n for _ in range(m)] + + for y in range(1, m): + for x in range(1, n): + dp[y][x] = dp[y - 1][x] + dp[y][x - 1] + + return dp[m - 1][n - 1] From 195d9b95528d3891db620a977d4187b8c53f7b58 Mon Sep 17 00:00:00 2001 From: Dusuna <94776135+dusunax@users.noreply.github.com> Date: Sat, 25 Jan 2025 02:46:07 +0900 Subject: [PATCH 6/6] add solution: set-matrix-zeroes --- set-matrix-zeroes/dusunax.py | 67 ++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 set-matrix-zeroes/dusunax.py diff --git a/set-matrix-zeroes/dusunax.py b/set-matrix-zeroes/dusunax.py new file mode 100644 index 000000000..b43766109 --- /dev/null +++ b/set-matrix-zeroes/dusunax.py @@ -0,0 +1,67 @@ +''' +# 73. Set Matrix Zeroes +# solution reference: https://www.algodale.com/problems/set-matrix-zeroes/ +''' +class Solution: + ''' + ### TC is O(m * n): + - iterating through every cells, to find the zero cells. = O(m * n) 1️⃣ + - iterating through every cells, to update the rows. = O(m * n) 2️⃣ + - iterating through every cells, to update the columns. = O(m * n) 3️⃣ + + ### SC is O(m + n): + - using each set to store the rows(O(m)) and columns(O(n)) that have zero. = O(m + n) + ''' + def setZeroesWithSet(self, matrix: List[List[int]]) -> None: + zero_rows = set() # SC: O(m) + zero_cols = set() # SC: O(n) + + for r in range(len(matrix)): # TC: O(m * n) + for c in range(len(matrix[0])): + if matrix[r][c] == 0: + zero_rows.add(r) + zero_cols.add(c) + + for r in zero_rows: # TC: O(m * n) + for i in range(len(matrix[0])): + matrix[r][i] = 0 + + for c in zero_cols: # TC: O(m * n) + for i in range(len(matrix)): + matrix[i][c] = 0 + + ''' + ### TC is O(m * n): + - check if the first row or column has zero. = O(m + n) + - iterating through every cells, if it has zero, mark the first row and column. = O(m * n) 1️⃣ + - update the matrix based on the marks(0) in the first row and column. = O(m * n) 2️⃣ + - if the first row or column has zero, iterating through every cells, in the first row or column and updating it. = O(m + n) + + ### SC is O(1): + - using the first_row_has_zero and first_col_has_zero to store the zero information. = O(1) + ''' + def setZeroesWithMarkerAndVariable(self, matrix: List[List[int]]) -> None: + rows = len(matrix) + cols = len(matrix[0]) + + first_row_has_zero = any(matrix[0][j] == 0 for j in range(cols)) # TC: O(n), SC: O(1) + first_col_has_zero = any(matrix[i][0] == 0 for i in range(rows)) # TC: O(m), SC: O(1) + + for r in range(1, rows): # TC: O(m * n) + for c in range(1, cols): + if matrix[r][c] == 0: + matrix[r][0] = 0 + matrix[0][c] = 0 + + for r in range(1, rows): # TC: O(m * n) + for c in range(1, cols): + if matrix[r][0] == 0 or matrix[0][c] == 0: + matrix[r][c] = 0 + + if first_row_has_zero: + for c in range(cols): # TC: O(n) + matrix[0][c] = 0 + + if first_col_has_zero: + for r in range(rows): # TC: O(m) + matrix[r][0] = 0