Skip to content

[SunaDu] Week 4 #811

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jan 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions coin-change/dusunax.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'''
# 322. Coin Change

use a queue for BFS & iterate through the coins and check the amount is down to 0.
use a set to the visited check.

## Time and Space Complexity

```
TC: O(n * Amount)
SC: O(Amount)
```

#### TC is O(n * Amount):
- sorting the coins = O(n log n)
- reversing the coins = O(n)
- iterating through the queue = O(Amount)
- iterating through the coins and check the remaining amount is down to 0 = O(n)

#### SC is O(Amount):
- using a queue to store (the remaining amount, the count of coins) tuple = O(Amount)
- using a set to store the visited check = O(Amount)
'''
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
if amount == 0:
return 0
if len(coins) == 1 and coins[0] == amount:
return 1

coins.sort() # TC: O(n log n)
coins.reverse() # TC: O(n)

queue = deque([(amount, 0)]) # SC: O(Amount)
visited = set() # SC: O(Amount)

while queue: # TC: O(Amount)
remain, count = queue.popleft()

for coin in coins: # TC: O(n)
next_remain = remain - coin

if next_remain == 0:
return count + 1
if next_remain > 0 and next_remain not in visited:
queue.append((next_remain, count + 1))
visited.add(next_remain)

return -1
77 changes: 77 additions & 0 deletions merge-two-sorted-lists/dusunax.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
'''
# 21. Merge Two Sorted Lists

A. iterative approach: use a two pointers to merge the two lists.
B. recursive approach: use recursion to merge the two lists.


## Time and Space Complexity

### A. Iterative Approach

```
TC: O(n + m)
SC: O(1)
```

#### TC is O(n + m):
- iterating through the two lists just once for merge two sorted lists. = O(n + m)

#### SC is O(1):
- temp node is used to store the result. = O(1)

### B. Recursive Approach

```
TC: O(n + m)
SC: O(n + m)
```

#### TC is O(n + m):
- iterating through the two lists just once for merge two sorted lists. = O(n + m)

#### SC is O(n + m):
- because of the recursive call stack. = O(n + m)
'''
class Solution:
'''
A. Iterative Approach
- use a temp node to store the result.
- use a current node to iterate through the two lists.
'''
def mergeTwoListsIterative(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
temp = ListNode(-1)
current = temp

while list1 is not None and list2 is not None:
if list1.val < list2.val:
current.next = list1
list1 = list1.next
else:
current.next = list2
list2 = list2.next
current = current.next

if list1 is not None:
current.next = list1
elif list2 is not None:
current.next = list2

return temp.next

'''
B. Recursive Approach
- use recursion to merge the two lists.
'''
def mergeTwoListsRecursive(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
if list1 is None:
return list2
elif list2 is None:
return list1

if list1.val < list2.val:
list1.next = self.mergeTwoLists(list1.next, list2)
return list1
else:
list2.next = self.mergeTwoLists(list1, list2.next)
return list2
63 changes: 63 additions & 0 deletions missing-number/dusunax.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
'''
# 268. Missing Number

A. iterative approach: sort the array and find the missing number.
B. XOR approach: use XOR to find the missing number.
- a ^ a = 0, a ^ 0 = a

## Time and Space Complexity

### A. Iterative Approach

```
TC: O(n log n)
SC: O(1)
```

#### TC is O(n):
- sorting the array. = O(n log n)
- iterating through the array just once to find the missing number. = O(n)
Comment on lines +17 to +19
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

선아님 말씀대로라면 시간복잡도는 O(n logn)이어야 하지 않을까요?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 네 잘못 작성했네요 감사합니다!


#### SC is O(1):
- no extra space is used. = O(1)

### B. XOR Approach

```
TC: O(n)
SC: O(1)
```

#### TC is O(n):
- iterating through the array just once to find the missing number. = O(n)

#### SC is O(1):
- no extra space is used. = O(1)

'''
class Solution:
'''
A. Iterative Approach
'''
def missingNumberIterative(self, nums: List[int]) -> int:
nums.sort()
n = len(nums)

for i in range(n):
if nums[i] != i:
return i
return n

'''
B. XOR Approach
'''
def missingNumberXOR(self, nums: List[int]) -> int:
n = len(nums)
xor_nums = 0

for i in range(n + 1):
if i < n:
xor_nums ^= nums[i]
xor_nums ^= i

return xor_nums
78 changes: 78 additions & 0 deletions palindromic-substrings/dusunax.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
'''
# 647. Palindromic Substrings

A. use dynamic programming table to store the palindrome status.
B. use two pointers to expand around the center.

## Time and Space Complexity

### A. Dynamic Programming Table
```
TC: O(n^2)
SC: O(n^2)
```

#### TC is O(n^2):
- filling DP table by iterating through all substrings.
- each cell (i, j) checks if a substring is a palindrome & counting the cases = O(n^2)

#### SC is O(n^2):
- storing the n x n dp table. = O(n^2)

### B. Expand Around Center
```
TC: O(n^2)
SC: O(1)
```

#### TC is O(n^2):
- for each char, expand outwards to check for palindromes. = O(n^2)

#### SC is O(1):
- no additional data structures are used. `count` is a single integer. = O(1)
'''
class Solution:
def countSubstringsDPTable(self, s: str) -> int:
'''
A. Dynamic Programming Table
'''
n = len(s)
dp = [[False] * n for _ in range(n)] # List comprehension. = SC: O(n^2)
count = 0

for i in range(n): # TC: O(n)
dp[i][i] = True
count += 1

for i in range(n - 1):
if s[i] == s[i + 1]:
dp[i][i + 1] = True
count += 1

for s_len in range(3, n + 1): # TC: O(n)
for i in range(n - s_len + 1): # TC: O(n)
j = i + s_len - 1

if s[i] == s[j] and dp[i + 1][j - 1]:
dp[i][j] = True
count += 1

return count
def countSubstrings(self, s: str) -> int:
'''
B. Expand Around Center
'''
count = 0

def expand(left, right):
nonlocal count
while left >= 0 and right < len(s) and s[left] == s[right]: # TC: O(n)
count += 1
left -= 1
right += 1

for i in range(len(s)): # TC: O(n)
expand(i, i)
expand(i, i + 1)

return count
52 changes: 52 additions & 0 deletions word-search/dusunax.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'''
# 79. Word Search

use backtracking(DFS) to search for the word in the board.

## Time and Space Complexity

```
TC: O(n * m * 4^L)
SC: O(L)
```

#### TC is O(n * m * 4^L):
- n is the number of rows in the board.
- m is the number of columns in the board.
- L is the length of the word.
- 4^L is the number of directions we can go at each step. (explores 4 branches recursively)

#### SC is O(L):
- modifying the board in-place to mark visited cells. = O(L)
'''
class Solution:
def exist(self, board: List[List[str]], word: str) -> bool:
rows = len(board)
cols = len(board[0])

def backtracking(i, j, word_index): # TC: O(4^L), SC: O(L)
if word_index == len(word):
return True

if i < 0 or i >= rows or j < 0 or j >= cols or board[i][j] != word[word_index]:
return False

temp = board[i][j]
board[i][j] = "."

found = (
backtracking(i + 1, j, word_index + 1) or
backtracking(i - 1, j, word_index + 1) or
backtracking(i, j + 1, word_index + 1) or
backtracking(i, j - 1, word_index + 1)
)
board[i][j] = temp

return found

for row in range(rows): # TC: O(n * m)
for col in range(cols):
if backtracking(row, col, 0):
return True

return False
Loading