Skip to content

Commit 33558fa

Browse files
authored
Merge pull request #811 from dusunax/main
[SunaDu] Week 4
2 parents 41a2c03 + cb5c505 commit 33558fa

File tree

5 files changed

+319
-0
lines changed

5 files changed

+319
-0
lines changed

coin-change/dusunax.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
'''
2+
# 322. Coin Change
3+
4+
use a queue for BFS & iterate through the coins and check the amount is down to 0.
5+
use a set to the visited check.
6+
7+
## Time and Space Complexity
8+
9+
```
10+
TC: O(n * Amount)
11+
SC: O(Amount)
12+
```
13+
14+
#### TC is O(n * Amount):
15+
- sorting the coins = O(n log n)
16+
- reversing the coins = O(n)
17+
- iterating through the queue = O(Amount)
18+
- iterating through the coins and check the remaining amount is down to 0 = O(n)
19+
20+
#### SC is O(Amount):
21+
- using a queue to store (the remaining amount, the count of coins) tuple = O(Amount)
22+
- using a set to store the visited check = O(Amount)
23+
'''
24+
class Solution:
25+
def coinChange(self, coins: List[int], amount: int) -> int:
26+
if amount == 0:
27+
return 0
28+
if len(coins) == 1 and coins[0] == amount:
29+
return 1
30+
31+
coins.sort() # TC: O(n log n)
32+
coins.reverse() # TC: O(n)
33+
34+
queue = deque([(amount, 0)]) # SC: O(Amount)
35+
visited = set() # SC: O(Amount)
36+
37+
while queue: # TC: O(Amount)
38+
remain, count = queue.popleft()
39+
40+
for coin in coins: # TC: O(n)
41+
next_remain = remain - coin
42+
43+
if next_remain == 0:
44+
return count + 1
45+
if next_remain > 0 and next_remain not in visited:
46+
queue.append((next_remain, count + 1))
47+
visited.add(next_remain)
48+
49+
return -1

merge-two-sorted-lists/dusunax.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
'''
2+
# 21. Merge Two Sorted Lists
3+
4+
A. iterative approach: use a two pointers to merge the two lists.
5+
B. recursive approach: use recursion to merge the two lists.
6+
7+
8+
## Time and Space Complexity
9+
10+
### A. Iterative Approach
11+
12+
```
13+
TC: O(n + m)
14+
SC: O(1)
15+
```
16+
17+
#### TC is O(n + m):
18+
- iterating through the two lists just once for merge two sorted lists. = O(n + m)
19+
20+
#### SC is O(1):
21+
- temp node is used to store the result. = O(1)
22+
23+
### B. Recursive Approach
24+
25+
```
26+
TC: O(n + m)
27+
SC: O(n + m)
28+
```
29+
30+
#### TC is O(n + m):
31+
- iterating through the two lists just once for merge two sorted lists. = O(n + m)
32+
33+
#### SC is O(n + m):
34+
- because of the recursive call stack. = O(n + m)
35+
'''
36+
class Solution:
37+
'''
38+
A. Iterative Approach
39+
- use a temp node to store the result.
40+
- use a current node to iterate through the two lists.
41+
'''
42+
def mergeTwoListsIterative(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
43+
temp = ListNode(-1)
44+
current = temp
45+
46+
while list1 is not None and list2 is not None:
47+
if list1.val < list2.val:
48+
current.next = list1
49+
list1 = list1.next
50+
else:
51+
current.next = list2
52+
list2 = list2.next
53+
current = current.next
54+
55+
if list1 is not None:
56+
current.next = list1
57+
elif list2 is not None:
58+
current.next = list2
59+
60+
return temp.next
61+
62+
'''
63+
B. Recursive Approach
64+
- use recursion to merge the two lists.
65+
'''
66+
def mergeTwoListsRecursive(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
67+
if list1 is None:
68+
return list2
69+
elif list2 is None:
70+
return list1
71+
72+
if list1.val < list2.val:
73+
list1.next = self.mergeTwoLists(list1.next, list2)
74+
return list1
75+
else:
76+
list2.next = self.mergeTwoLists(list1, list2.next)
77+
return list2

missing-number/dusunax.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
'''
2+
# 268. Missing Number
3+
4+
A. iterative approach: sort the array and find the missing number.
5+
B. XOR approach: use XOR to find the missing number.
6+
- a ^ a = 0, a ^ 0 = a
7+
8+
## Time and Space Complexity
9+
10+
### A. Iterative Approach
11+
12+
```
13+
TC: O(n log n)
14+
SC: O(1)
15+
```
16+
17+
#### TC is O(n):
18+
- sorting the array. = O(n log n)
19+
- iterating through the array just once to find the missing number. = O(n)
20+
21+
#### SC is O(1):
22+
- no extra space is used. = O(1)
23+
24+
### B. XOR Approach
25+
26+
```
27+
TC: O(n)
28+
SC: O(1)
29+
```
30+
31+
#### TC is O(n):
32+
- iterating through the array just once to find the missing number. = O(n)
33+
34+
#### SC is O(1):
35+
- no extra space is used. = O(1)
36+
37+
'''
38+
class Solution:
39+
'''
40+
A. Iterative Approach
41+
'''
42+
def missingNumberIterative(self, nums: List[int]) -> int:
43+
nums.sort()
44+
n = len(nums)
45+
46+
for i in range(n):
47+
if nums[i] != i:
48+
return i
49+
return n
50+
51+
'''
52+
B. XOR Approach
53+
'''
54+
def missingNumberXOR(self, nums: List[int]) -> int:
55+
n = len(nums)
56+
xor_nums = 0
57+
58+
for i in range(n + 1):
59+
if i < n:
60+
xor_nums ^= nums[i]
61+
xor_nums ^= i
62+
63+
return xor_nums

palindromic-substrings/dusunax.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
'''
2+
# 647. Palindromic Substrings
3+
4+
A. use dynamic programming table to store the palindrome status.
5+
B. use two pointers to expand around the center.
6+
7+
## Time and Space Complexity
8+
9+
### A. Dynamic Programming Table
10+
```
11+
TC: O(n^2)
12+
SC: O(n^2)
13+
```
14+
15+
#### TC is O(n^2):
16+
- filling DP table by iterating through all substrings.
17+
- each cell (i, j) checks if a substring is a palindrome & counting the cases = O(n^2)
18+
19+
#### SC is O(n^2):
20+
- storing the n x n dp table. = O(n^2)
21+
22+
### B. Expand Around Center
23+
```
24+
TC: O(n^2)
25+
SC: O(1)
26+
```
27+
28+
#### TC is O(n^2):
29+
- for each char, expand outwards to check for palindromes. = O(n^2)
30+
31+
#### SC is O(1):
32+
- no additional data structures are used. `count` is a single integer. = O(1)
33+
'''
34+
class Solution:
35+
def countSubstringsDPTable(self, s: str) -> int:
36+
'''
37+
A. Dynamic Programming Table
38+
'''
39+
n = len(s)
40+
dp = [[False] * n for _ in range(n)] # List comprehension. = SC: O(n^2)
41+
count = 0
42+
43+
for i in range(n): # TC: O(n)
44+
dp[i][i] = True
45+
count += 1
46+
47+
for i in range(n - 1):
48+
if s[i] == s[i + 1]:
49+
dp[i][i + 1] = True
50+
count += 1
51+
52+
for s_len in range(3, n + 1): # TC: O(n)
53+
for i in range(n - s_len + 1): # TC: O(n)
54+
j = i + s_len - 1
55+
56+
if s[i] == s[j] and dp[i + 1][j - 1]:
57+
dp[i][j] = True
58+
count += 1
59+
60+
return count
61+
def countSubstrings(self, s: str) -> int:
62+
'''
63+
B. Expand Around Center
64+
'''
65+
count = 0
66+
67+
def expand(left, right):
68+
nonlocal count
69+
while left >= 0 and right < len(s) and s[left] == s[right]: # TC: O(n)
70+
count += 1
71+
left -= 1
72+
right += 1
73+
74+
for i in range(len(s)): # TC: O(n)
75+
expand(i, i)
76+
expand(i, i + 1)
77+
78+
return count

word-search/dusunax.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
'''
2+
# 79. Word Search
3+
4+
use backtracking(DFS) to search for the word in the board.
5+
6+
## Time and Space Complexity
7+
8+
```
9+
TC: O(n * m * 4^L)
10+
SC: O(L)
11+
```
12+
13+
#### TC is O(n * m * 4^L):
14+
- n is the number of rows in the board.
15+
- m is the number of columns in the board.
16+
- L is the length of the word.
17+
- 4^L is the number of directions we can go at each step. (explores 4 branches recursively)
18+
19+
#### SC is O(L):
20+
- modifying the board in-place to mark visited cells. = O(L)
21+
'''
22+
class Solution:
23+
def exist(self, board: List[List[str]], word: str) -> bool:
24+
rows = len(board)
25+
cols = len(board[0])
26+
27+
def backtracking(i, j, word_index): # TC: O(4^L), SC: O(L)
28+
if word_index == len(word):
29+
return True
30+
31+
if i < 0 or i >= rows or j < 0 or j >= cols or board[i][j] != word[word_index]:
32+
return False
33+
34+
temp = board[i][j]
35+
board[i][j] = "."
36+
37+
found = (
38+
backtracking(i + 1, j, word_index + 1) or
39+
backtracking(i - 1, j, word_index + 1) or
40+
backtracking(i, j + 1, word_index + 1) or
41+
backtracking(i, j - 1, word_index + 1)
42+
)
43+
board[i][j] = temp
44+
45+
return found
46+
47+
for row in range(rows): # TC: O(n * m)
48+
for col in range(cols):
49+
if backtracking(row, col, 0):
50+
return True
51+
52+
return False

0 commit comments

Comments
 (0)