Skip to content

Commit 4bc9ef5

Browse files
authored
Merge pull request #2123 from unpo88/main
[unpo88] WEEK 04 solutions
2 parents 4189053 + 11f97b1 commit 4bc9ef5

File tree

5 files changed

+338
-0
lines changed

5 files changed

+338
-0
lines changed

β€Žcoin-change/unpo88.pyβ€Ž

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
class Solution:
2+
def coinChange(self, coins: list[int], amount: int) -> int:
3+
dp = [float('inf')] * (amount + 1)
4+
dp[0] = 0
5+
6+
for coin in coins:
7+
for x in range(coin, amount + 1):
8+
dp[x] = min(dp[x], dp[x - coin] + 1)
9+
10+
return dp[amount] if dp[amount] != float('inf') else -1
11+
12+
"""
13+
================================================================================
14+
풀이 κ³Όμ •
15+
================================================================================
16+
17+
[1μ°¨ μ‹œλ„] μ™„μ „ νƒμƒ‰μœΌλ‘œ μ ‘κ·Όν•˜λ©΄?
18+
────────────────────────────────────────────────────────────────────────────────
19+
1. λͺ¨λ“  동전 쑰합을 μ‹œλ„ν•΄λ³΄λ©΄ μ–΄λ–¨κΉŒ?
20+
2. coins = [1, 2, 5], amount = 11
21+
- 5 + 5 + 1 = 11 (3개)
22+
- 5 + 2 + 2 + 2 = 11 (4개)
23+
- 1 + 1 + ... (11개)
24+
... λ„ˆλ¬΄ λ§Žμ€ 경우의 수!
25+
26+
3. 문제: μ‹œκ°„λ³΅μž‘λ„κ°€ λ„ˆλ¬΄ λ†’μŒ (μ§€μˆ˜ μ‹œκ°„)
27+
4. 더 효율적인 방법이 ν•„μš”ν•¨ β†’ DP둜 μ ‘κ·Όν•˜μž!
28+
29+
────────────────────────────────────────────────────────────────────────────────
30+
[2μ°¨ μ‹œλ„] DP μ΄ˆκΈ°ν™”μ™€ 점화식
31+
────────────────────────────────────────────────────────────────────────────────
32+
5. dp[i] = i원을 λ§Œλ“œλŠ”λ° ν•„μš”ν•œ μ΅œμ†Œ 동전 개수
33+
6. μ΄ˆκΈ°ν™”:
34+
- dp[0] = 0 (0원 λ§Œλ“€κΈ° = 동전 0개)
35+
- dp[1~amount] = 아직 계산 μ•ˆ 됨
36+
37+
dp = [float('inf')] * (amount + 1)
38+
dp[0] = 0
39+
40+
7. 점화식:
41+
- 각 동전 coin에 λŒ€ν•΄
42+
- dp[x] = min(dp[x], dp[x - coin] + 1)
43+
- 의미: "x원 = (x-coin)원 + coin 1개"
44+
45+
8. Eample) coins = [1, 2, 5], amount = 11
46+
47+
초기: dp = [0, inf, inf, inf, ..., inf]
48+
49+
동전 1 처리:
50+
dp[1] = min(inf, dp[0]+1) = 1
51+
dp[2] = min(inf, dp[1]+1) = 2
52+
dp[3] = min(inf, dp[2]+1) = 3
53+
...
54+
55+
동전 2 처리:
56+
dp[2] = min(2, dp[0]+1) = 1 # 2원 동전 1개!
57+
dp[3] = min(3, dp[1]+1) = 2 # 2+1
58+
dp[4] = min(4, dp[2]+1) = 2 # 2+2
59+
...
60+
61+
동전 5 처리:
62+
dp[5] = min(5, dp[0]+1) = 1 # 5원 동전 1개!
63+
dp[6] = min(6, dp[1]+1) = 2 # 5+1
64+
dp[10] = min(10, dp[5]+1) = 2 # 5+5
65+
dp[11] = min(11, dp[6]+1) = 3 # 5+5+1
66+
67+
68+
[μ΅œμ’… κ΅¬ν˜„] Bottom-Up DP
69+
────────────────────────────────────────────────────────────────────────────────
70+
12. λͺ¨λ“  동전에 λŒ€ν•΄ 반볡
71+
13. 각 λ™μ „μœΌλ‘œ λ§Œλ“€ 수 μžˆλŠ” λͺ¨λ“  κΈˆμ•‘ μ—…λ°μ΄νŠΈ
72+
14. λΆˆκ°€λŠ₯ν•˜λ©΄ -1 λ°˜ν™˜ (dp[amount]κ°€ μ—¬μ „νžˆ λ¬΄ν•œλŒ€)
73+
74+
for coin in coins:
75+
for x in range(coin, amount + 1):
76+
dp[x] = min(dp[x], dp[x - coin] + 1)
77+
78+
return dp[amount] if dp[amount] != float('inf') else -1
79+
80+
15. μ‹œκ°„λ³΅μž‘λ„: O(amount Γ— coins) - 효율적!
81+
16. κ³΅κ°„λ³΅μž‘λ„: O(amount) - dp λ°°μ—΄
82+
"""
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
class Solution:
2+
def findMin(self, nums: List[int]) -> int:
3+
left, right = 0, len(nums) - 1
4+
5+
while left < right:
6+
mid = (left + right) // 2
7+
8+
if nums[mid] > nums[right]:
9+
left = mid + 1
10+
else:
11+
right = mid
12+
13+
return nums[left]
14+
15+
"""
16+
================================================================================
17+
풀이 κ³Όμ •
18+
================================================================================
19+
20+
[1μ°¨ μ‹œλ„] 이진 탐색 적용 - κΈ°λ³Έ ꡬ쑰
21+
────────────────────────────────────────────────────────────────────────────────
22+
1. log(n) μ‹œκ°„ λ³΅μž‘λ„λ₯Ό λ§Œμ‘±μ‹œν‚€λŠ” 이진 탐색 ꡬ쑰둜 μ΅œμ†Œκ°’μ„ 찾으면 될 것 κ°™μŒ
23+
24+
left, right = 0, len(nums) - 1
25+
26+
while left < right:
27+
mid = (left + right) // 2
28+
29+
if nums[mid] > nums[right]:
30+
left = mid + 1
31+
else:
32+
right = mid
33+
34+
return nums[left]
35+
36+
2. μ‹œκ°„λ³΅μž‘λ„: O(log n) - 이진 탐색
37+
3. κ³΅κ°„λ³΅μž‘λ„: O(1) - μΆ”κ°€ 곡간 μ‚¬μš© μ•ˆ 함
38+
"""
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Definition for a binary tree node.
2+
# class TreeNode:
3+
# def __init__(self, val=0, left=None, right=None):
4+
# self.val = val
5+
# self.left = left
6+
# self.right = right
7+
class Solution:
8+
def maxDepth(self, root: Optional[TreeNode]) -> int:
9+
if not root:
10+
return 0
11+
12+
left_depth = self.maxDepth(root.left)
13+
right_depth = self.maxDepth(root.right)
14+
15+
return max(left_depth, right_depth) + 1
16+
17+
"""
18+
================================================================================
19+
풀이 κ³Όμ •
20+
================================================================================
21+
22+
[1μ°¨ μ‹œλ„] μž¬κ·€λ‘œ 깊이 카운트 - None은 0
23+
────────────────────────────────────────────────────────────────────────────────
24+
1. 빈 λ…Έλ“œ(None)λŠ” κΉŠμ΄κ°€ 0이
25+
2. leaf λ…Έλ“œμ—μ„œ μ–‘μͺ½ μžμ‹μ΄ None이면 λ‘˜ λ‹€ 0을 λ°˜ν™˜
26+
3. 그러면 leaf λ…Έλ“œλŠ” max(0, 0) + 1 = 1이 됨 (자기 μžμ‹ λ§Œ 카운트)
27+
28+
def maxDepth(self, root):
29+
if not root:
30+
return 0 # 빈 λ…Έλ“œλŠ” 0
31+
32+
left = self.maxDepth(root.left)
33+
right = self.maxDepth(root.right)
34+
35+
return max(left, right) + 1 # 더 κΉŠμ€ μͺ½ + λ‚˜ μžμ‹ (1)
36+
37+
4. λ™μž‘ μ˜ˆμ‹œ:
38+
트리: 1
39+
/ \
40+
2 3
41+
/
42+
4
43+
44+
maxDepth(4) β†’ max(0, 0) + 1 = 1
45+
maxDepth(2) β†’ max(1, 0) + 1 = 2
46+
maxDepth(3) β†’ max(0, 0) + 1 = 1
47+
maxDepth(1) β†’ max(2, 1) + 1 = 3 βœ“
48+
49+
50+
5. μ‹œκ°„λ³΅μž‘λ„: O(n) - λͺ¨λ“  λ…Έλ“œλ₯Ό 1λ²ˆμ”© λ°©λ¬Έ
51+
6. κ³΅κ°„λ³΅μž‘λ„: O(h) - μž¬κ·€ μŠ€νƒ, hλŠ” 트리 높이
52+
"""
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Definition for singly-linked list.
2+
# class ListNode:
3+
# def __init__(self, val=0, next=None):
4+
# self.val = val
5+
# self.next = next
6+
class Solution:
7+
def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
8+
dummy = ListNode()
9+
head = dummy
10+
11+
while list1 and list2:
12+
if list1.val < list2.val:
13+
head.next = list1
14+
list1 = list1.next
15+
else:
16+
head.next = list2
17+
list2 = list2.next
18+
head = head.next
19+
20+
if list1:
21+
head.next = list1
22+
elif list2:
23+
head.next = list2
24+
25+
return dummy.next
26+
27+
"""
28+
================================================================================
29+
풀이 κ³Όμ •
30+
================================================================================
31+
32+
[1μ°¨ μ‹œλ„] Dummy Node ν™œμš©
33+
────────────────────────────────────────────────────────────────────────────────
34+
1. μž‘μ€ 값을 κ°€μ§„ λ…Έλ“œλ₯Ό κ³¨λΌμ„œ head에 μ—°κ²°ν•˜λŠ” λ°©μ‹μœΌλ‘œ 문제λ₯Ό ν’€μ–΄λ³΄μž.
35+
2. ν•œ μͺ½ λ¦¬μŠ€νŠΈκ°€ λΉ„κ²Œ 되면 남은 λ…Έλ“œλ₯Ό κ·Έλƒ₯ μ—°κ²°ν•΄μ£Όλ©΄ 될 것 κ°™μŒ.
36+
37+
dummy = ListNode()
38+
head = dummy
39+
40+
while list1 and list2:
41+
if list1.val < list2.val:
42+
head.next = list1
43+
list1 = list1.next
44+
else:
45+
head.next = list2
46+
list2 = list2.next
47+
head = head.next
48+
49+
if list1:
50+
head.next = list1
51+
elif list2:
52+
head.next = list2
53+
54+
return dummy.next
55+
"""

β€Žword-search/unpo88.pyβ€Ž

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
class Solution:
2+
def exist(self, board: list[list[str]], word: str) -> bool:
3+
if not board or not board[0]:
4+
return False
5+
6+
m, n = len(board), len(board[0])
7+
8+
dx = [-1, 1, 0, 0]
9+
dy = [0, 0, -1, 1]
10+
11+
def dfs(x, y, index):
12+
if index == len(word):
13+
return True
14+
15+
if x < 0 or x >= m or y < 0 or y >= n or board[x][y] != word[index]:
16+
return False
17+
18+
temp = board[x][y]
19+
board[x][y] = '#'
20+
21+
for i in range(4):
22+
nx = x + dx[i]
23+
ny = y + dy[i]
24+
if dfs(nx, ny, index + 1):
25+
return True
26+
27+
board[x][y] = temp
28+
return False
29+
30+
for i in range(m):
31+
for j in range(n):
32+
if board[i][j] == word[0] and dfs(i, j, 0):
33+
return True
34+
35+
return False
36+
37+
"""
38+
================================================================================
39+
풀이 κ³Όμ •
40+
================================================================================
41+
42+
[1μ°¨ μ‹œλ„] DFS + λ°©ν–₯ λ°°μ—΄λ‘œ μ ‘κ·Ό
43+
────────────────────────────────────────────────────────────────────────────────
44+
1. κ²©μžμ—μ„œ μƒν•˜μ’Œμš°λ‘œ μ΄λ™ν•˜λ©° 단어λ₯Ό μ°Ύμ•„μ•Ό 함
45+
2. 같은 셀은 ν•œ 번만 μ‚¬μš© κ°€λŠ₯ β†’ λ°©λ¬Έ 체크 ν•„μš”
46+
3. DFS(깊이 μš°μ„  탐색) + λ°±νŠΈλž˜ν‚ΉμœΌλ‘œ ν’€λ©΄ 될 것 κ°™μŒ
47+
4. μƒν•˜μ’Œμš° 이동을 μœ„ν•œ dx, dy λ°°μ—΄ λ§Œλ“€μž
48+
49+
dx = [-1, 1, 0, 0]
50+
dy = [0, 0, -1, 1]
51+
52+
53+
[2μ°¨ μ‹œλ„] DFS ν•¨μˆ˜ ꡬ쑰 섀계
54+
────────────────────────────────────────────────────────────────────────────────
55+
5. dfs(x, y, index) ν˜•νƒœλ‘œ ν˜„μž¬ μœ„μΉ˜μ™€ λ‹¨μ–΄μ˜ 인덱슀λ₯Ό 좔적
56+
6. base case:
57+
- index == len(word): 단어 λκΉŒμ§€ 찾음 β†’ True
58+
- λ²”μœ„ 벗어남 or 문자 뢈일치 β†’ False
59+
60+
def dfs(x, y, index):
61+
if index == len(word):
62+
return True
63+
64+
if x < 0 or x >= m or y < 0 or y >= n or board[x][y] != word[index]:
65+
return False
66+
67+
7. λ°©λ¬Έν•œ 셀은 μ–΄λ–»κ²Œ ν‘œμ‹œν•˜μ§€?
68+
69+
70+
[3μ°¨ μ‹œλ„] λ°©λ¬Έ ν‘œμ‹œμ™€ λ°±νŠΈλž˜ν‚Ή
71+
────────────────────────────────────────────────────────────────────────────────
72+
8. ν˜„μž¬ 셀을 '#' 같은 특수 문자둜 μž„μ‹œ λ³€κ²½ (λ°©λ¬Έ ν‘œμ‹œ)
73+
9. 4λ°©ν–₯으둜 μž¬κ·€ 탐색
74+
10. 탐색 μ‹€νŒ¨ μ‹œ μ›λž˜ κ°’μœΌλ‘œ 볡원 (λ°±νŠΈλž˜ν‚Ή)
75+
76+
temp = board[x][y]
77+
board[x][y] = '#'
78+
79+
for i in range(4):
80+
nx = x + dx[i]
81+
ny = y + dy[i]
82+
if dfs(nx, ny, index + 1):
83+
return True
84+
85+
board[x][y] = temp
86+
return False
87+
88+
89+
[4μ°¨ μ‹œλ„] μ‘°κΈ° μ’…λ£Œ μ΅œμ ν™” μΆ”κ°€
90+
────────────────────────────────────────────────────────────────────────────────
91+
11. 빈 λ³΄λ“œλŠ” λ°”λ‘œ False λ°˜ν™˜
92+
12. 첫 κΈ€μžκ°€ μΌμΉ˜ν•˜λŠ” μ…€μ—μ„œλ§Œ DFS μ‹œμž‘ (λΆˆν•„μš”ν•œ 탐색 λ°©μ§€)
93+
94+
if not board or not board[0]:
95+
return False
96+
97+
for i in range(m):
98+
for j in range(n):
99+
if board[i][j] == word[0] and dfs(i, j, 0):
100+
return True
101+
102+
103+
[μ΅œμ’… κ΅¬ν˜„] μ΅œμ ν™”λœ DFS 탐색
104+
────────────────────────────────────────────────────────────────────────────────
105+
13. μ‘°κΈ° μ’…λ£Œλ‘œ λΆˆν•„μš”ν•œ 탐색 제거
106+
14. λ°±νŠΈλž˜ν‚ΉμœΌλ‘œ λ°©λ¬Έ μƒνƒœ 관리
107+
15. ν•˜λ‚˜λΌλ„ μ„±κ³΅ν•˜λ©΄ μ¦‰μ‹œ True λ°˜ν™˜
108+
109+
16. μ‹œκ°„λ³΅μž‘λ„: O(m * n * 4^L) - μ΅œμ•…μ˜ 경우, μ‘°κΈ° μ’…λ£Œλ‘œ μ‹€μ œλ‘œλŠ” 더 빠름
110+
17. κ³΅κ°„λ³΅μž‘λ„: O(L) - μž¬κ·€ 깊이
111+
"""

0 commit comments

Comments
Β (0)