Skip to content

Commit 2e9a2c5

Browse files
authored
Merge pull request #2084 from unpo88/main
[unpo88] WEEK 03 solutions
2 parents 3289b62 + fade13e commit 2e9a2c5

File tree

5 files changed

+296
-0
lines changed

5 files changed

+296
-0
lines changed

β€Žcombination-sum/unpo88.pyβ€Ž

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
class Solution:
2+
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
3+
result = []
4+
5+
def backtrack(start, current, current_sum):
6+
if current_sum == target:
7+
result.append(current[:])
8+
return
9+
10+
if current_sum > target:
11+
return
12+
13+
for i in range(start, len(candidates)):
14+
current.append(candidates[i])
15+
backtrack(i, current, current_sum + candidates[i])
16+
current.pop()
17+
18+
backtrack(0, [], 0)
19+
return result
20+
21+
22+
"""
23+
================================================================================
24+
풀이 κ³Όμ •
25+
================================================================================
26+
27+
1. 이거 λͺ¨λ“  κ°€λŠ₯ν•œ 쑰합을 μ°Ύμ•„μ•Όν•˜λŠ”λ° 합이 target을 λ„˜μœΌλ©΄ μ€‘λ‹¨λ˜μ•Όν•˜λ„€?
28+
2. λ¬Έμ œλŠ” 같은 숫자λ₯Ό μ—¬λŸ¬ 번 μ“Έ 수 μžˆλŠ”κ±΄λ°..
29+
3. λ°±νŠΈλž˜ν‚ΉμœΌλ‘œ μ ‘κ·Όν•΄μ•Όν•  것 같은데..
30+
31+
32+
[1μ°¨ μ‹œλ„] λ°±νŠΈλž˜ν‚Ή (Backtracking)
33+
────────────────────────────────────────────────────────────────────────────────
34+
4. λͺ¨λ“  쑰합을 νƒμƒ‰ν•˜λ˜, 쑰건에 λ§žμ§€ μ•ŠμœΌλ©΄ κ°€μ§€μΉ˜κΈ°
35+
5. 같은 숫자λ₯Ό μ—¬λŸ¬ 번 μ‚¬μš©ν•  수 μžˆμœΌλ―€λ‘œ μž¬κ·€ 호좜 μ‹œ 같은 μΈλ±μŠ€λΆ€ν„° μ‹œμž‘
36+
6. 쀑볡 μ‘°ν•© λ°©μ§€λ₯Ό μœ„ν•΄ start 인덱슀 μ‚¬μš©
37+
38+
result = []
39+
40+
def backtrack(start, current, current_sum):
41+
# target을 λ§Œμ‘±ν•˜λ©΄ 결과에 μΆ”κ°€
42+
if current_sum == target:
43+
result.append(current[:]) # λ³΅μ‚¬ν•΄μ„œ μΆ”κ°€
44+
return
45+
46+
# κ°€μ§€μΉ˜κΈ°: 합이 target 초과
47+
if current_sum > target:
48+
return
49+
50+
# μ‘°ν•© 탐색
51+
for i in range(start, len(candidates)):
52+
current.append(candidates[i])
53+
# 같은 숫자 μž¬μ‚¬μš© κ°€λŠ₯ν•˜λ―€λ‘œ iλΆ€ν„° μ‹œμž‘
54+
backtrack(i, current, current_sum + candidates[i])
55+
current.pop() # λ°±νŠΈλž˜ν‚Ή: μƒνƒœ 볡원
56+
57+
backtrack(0, [], 0)
58+
return result
59+
60+
7. Example: candidates = [2,3,6,7], target = 7
61+
62+
backtrack(0, [], 0)
63+
β”œβ”€ 2 μΆ”κ°€ β†’ backtrack(0, [2], 2)
64+
β”‚ β”œβ”€ 2 μΆ”κ°€ β†’ backtrack(0, [2,2], 4)
65+
β”‚ β”‚ β”œβ”€ 2 μΆ”κ°€ β†’ backtrack(0, [2,2,2], 6)
66+
β”‚ β”‚ β”‚ └─ 2 μΆ”κ°€ β†’ backtrack(0, [2,2,2,2], 8) β†’ 8 > 7 return
67+
β”‚ β”‚ └─ 3 μΆ”κ°€ β†’ backtrack(1, [2,2,3], 7) β†’ 7 == 7 βœ… [2,2,3]
68+
β”‚ └─ 3 μΆ”κ°€ β†’ backtrack(1, [2,3], 5)
69+
β”‚ └─ ... (탐색 계속)
70+
└─ 7 μΆ”κ°€ β†’ backtrack(3, [7], 7) β†’ 7 == 7 βœ… [7]
71+
72+
8. μ‹œκ°„ λ³΅μž‘λ„: O(N^(T/M))
73+
- N: candidates 길이
74+
- T: target κ°’
75+
- M: candidates의 μ΅œμ†Œκ°’
76+
9. 곡간 λ³΅μž‘λ„: O(T/M) - μž¬κ·€ 호좜 μŠ€νƒ 깊이
77+
"""

β€Ždecode-ways/unpo88.pyβ€Ž

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
class Solution:
2+
def numDecodings(self, s: str) -> int:
3+
# μ˜ˆμ™Έ 처리: "0"으둜 μ‹œμž‘ν•˜λ©΄ λΆˆκ°€λŠ₯
4+
if not s or s[0] == '0':
5+
return 0
6+
7+
n = len(s)
8+
dp = [0] * (n + 1)
9+
10+
# μ΄ˆκΈ°κ°’
11+
dp[0] = 1 # 빈 λ¬Έμžμ—΄
12+
dp[1] = 1 # 첫 번째 문자 (이미 "0" 체크함)
13+
14+
for i in range(2, n + 1):
15+
# ν•œ 자리 숫자 (1~9)
16+
if s[i-1] != '0':
17+
dp[i] += dp[i-1]
18+
19+
# 두 자리 숫자 (10~26)
20+
two_digit = int(s[i-2:i])
21+
if 10 <= two_digit <= 26:
22+
dp[i] += dp[i-2]
23+
24+
return dp[n]
25+
26+
27+
"""
28+
================================================================================
29+
풀이 κ³Όμ •
30+
================================================================================
31+
- "226" β†’ 2|2|6 (BBF), 22|6 (VF), 2|26 (BZ) β†’ 3κ°€μ§€ 방법 쑴재
32+
- DPλ₯Ό μ΄μš©ν•΄μ„œ 각 μœ„μΉ˜μ—μ„œ κ°€λŠ₯ν•œ λ””μ½”λ”© 경우의 수λ₯Ό 계산
33+
- ν•œ 자리(1~9)와 두 자리(10~26) 숫자λ₯Ό κ³ λ €ν•˜μ—¬ λˆ„μ 
34+
35+
[1μ°¨ μ‹œλ„]
36+
────────────────────────────────────────────────────────────────────────────────
37+
1. μ ‘κ·Ό 방법
38+
- DP λ°°μ—΄ μ‚¬μš©: dp[i] = λ¬Έμžμ—΄μ˜ μ²˜μŒλΆ€ν„° iλ²ˆμ§ΈκΉŒμ§€μ˜ λ””μ½”λ”© 경우의 수
39+
- 각 μœ„μΉ˜μ—μ„œ ν•œ 자리 숫자(1~9)둜 λ””μ½”λ”© κ°€λŠ₯ν•˜λ©΄ dp[i-1] λ”ν•˜κΈ°
40+
- 두 자리 숫자(10~26)둜 λ””μ½”λ”© κ°€λŠ₯ν•˜λ©΄ dp[i-2] λ”ν•˜κΈ°
41+
42+
2. κ΅¬ν˜„
43+
n = len(s)
44+
dp = [0] * (n + 1)
45+
46+
# μ΄ˆκΈ°κ°’ μ„€μ •
47+
dp[0] = 1 # 빈 λ¬Έμžμ—΄
48+
dp[1] = 1 # 첫 번째 문자 (0이 μ•„λ‹ˆλ©΄ 1κ°€μ§€)
49+
50+
for i in range(2, n + 1):
51+
# ν•œ 자리 숫자 (1~9)
52+
if s[i-1] != '0':
53+
dp[i] += dp[i-1]
54+
55+
# 두 자리 숫자 (10~26)
56+
two_digit = int(s[i-2:i])
57+
if 10 <= two_digit <= 26:
58+
dp[i] += dp[i-2]
59+
60+
3. μ˜ˆμ™Έ 처리
61+
- "0"으둜 μ‹œμž‘ν•˜λŠ” λ¬Έμžμ—΄μ€ λ””μ½”λ”© λΆˆκ°€λŠ₯ β†’ 0 λ°˜ν™˜
62+
- 빈 λ¬Έμžμ—΄ 체크
63+
64+
4. μ‹œκ°„ λ³΅μž‘λ„: O(n) - λ¬Έμžμ—΄μ„ ν•œ 번만 순회
65+
5. 곡간 λ³΅μž‘λ„: O(n) - DP λ°°μ—΄ μ‚¬μš©
66+
"""

β€Žmaximum-subarray/unpo88.pyβ€Ž

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
class Solution:
2+
def maxSubArray(self, nums: List[int]) -> int:
3+
current_sum = nums[0]
4+
max_sum = nums[0]
5+
6+
for i in range(1, len(nums)):
7+
# ν˜„μž¬ κ°’λΆ€ν„° μƒˆλ‘œ μ‹œμž‘ vs 이전 합에 μΆ”κ°€
8+
current_sum = max(nums[i], current_sum + nums[i])
9+
max_sum = max(max_sum, current_sum)
10+
11+
return max_sum
12+
13+
14+
"""
15+
================================================================================
16+
풀이 κ³Όμ •
17+
================================================================================
18+
19+
1. λΆ€λΆ„ λ°°μ—΄ 쀑 κ°€μž₯ 큰 합을 μ°Ύμ•„μ•Ό ν•˜λŠ”λ° μ–΄λ–»κ²Œ μ ‘κ·Όν•˜μ§€?
20+
2. Sliding Window? β†’ 음수/μ–‘μˆ˜κ°€ μ„žμ—¬μžˆμ–΄μ„œ μœˆλ„μš° 크기λ₯Ό μ–Έμ œ μ‘°μ ˆν• μ§€ 뢈λͺ…ν™•
21+
3. λͺ¨λ“  뢀뢄배열을 확인? β†’ O(nΒ²)이라 λΉ„νš¨μœ¨μ 
22+
4. 각 μœ„μΉ˜μ—μ„œ "ν˜„μž¬κΉŒμ§€μ˜ μ΅œλŒ€ λΆ€λΆ„ν•©"을 μΆ”μ ν•˜λ©΄ λ˜μ§€ μ•Šμ„κΉŒ?
23+
24+
25+
[1μ°¨ μ‹œλ„] Dynamic Programming
26+
────────────────────────────────────────────────────────────────────────────────
27+
5. 핡심 아이디어: 각 μœ„μΉ˜μ—μ„œ "이 μœ„μΉ˜λ₯Ό 끝으둜 ν•˜λŠ”" μ΅œλŒ€ λΆ€λΆ„λ°°μ—΄μ˜ ν•© 좔적
28+
6. current_sum = "ν˜„μž¬ μœ„μΉ˜λ₯Ό 끝으둜 ν•˜λŠ” μ΅œλŒ€ λΆ€λΆ„ν•©"
29+
7. λ§€ μœ„μΉ˜μ—μ„œ 선택: 이전 합에 μΆ”κ°€ vs μ—¬κΈ°μ„œ μƒˆλ‘œ μ‹œμž‘
30+
31+
current_sum = nums[0] # ν˜„μž¬ μœ„μΉ˜κΉŒμ§€μ˜ μ΅œλŒ€ λΆ€λΆ„ν•©
32+
max_sum = nums[0] # 전체 μ΅œλŒ“κ°’
33+
34+
for i in range(1, len(nums)):
35+
# 이전 합이 μ–‘μˆ˜λ©΄ 계속, 음수면 버리고 μƒˆλ‘œ μ‹œμž‘
36+
current_sum = max(nums[i], current_sum + nums[i])
37+
max_sum = max(max_sum, current_sum)
38+
39+
return max_sum
40+
41+
8. Example: nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
42+
43+
i=0: current=-2, max=-2
44+
i=1: max(1, -2+1=-1) = 1 (μƒˆλ‘œ μ‹œμž‘), max=1
45+
i=2: max(-3, 1-3=-2) = -2 (이어감), max=1
46+
i=3: max(4, -2+4=2) = 4 (μƒˆλ‘œ μ‹œμž‘), max=4
47+
i=4: max(-1, 4-1=3) = 3 (이어감), max=4
48+
i=5: max(2, 3+2=5) = 5 (이어감), max=5
49+
i=6: max(1, 5+1=6) = 6 (이어감), max=6 βœ“
50+
i=7: max(-5, 6-5=1) = 1 (이어감), max=6
51+
i=8: max(4, 1+4=5) = 5 (이어감), max=6
52+
53+
κ²°κ³Ό: [4, -1, 2, 1] = 6
54+
55+
9. μ™œ μž‘λ™ν•˜λŠ”κ°€?
56+
- λͺ¨λ“  뢀뢄배열은 μ–΄λ”˜κ°€μ—μ„œ 끝남
57+
- 각 μœ„μΉ˜μ—μ„œ "μ—¬κΈ°λ₯Ό 끝으둜 ν•˜λŠ” μ΅œλŒ“κ°’" 좔적
58+
- 이전 합이 음수면 λ²„λ¦¬λŠ” 게 이득 (Greedyν•œ 선택)
59+
- 이전 합이 μ–‘μˆ˜λ©΄ ν˜„μž¬ 값이 μŒμˆ˜μ—¬λ„ 계속 (예: 4 + (-1) = 3)
60+
61+
10. μ‹œκ°„ λ³΅μž‘λ„: O(n) - 배열을 ν•œ 번만 순회
62+
11. 곡간 λ³΅μž‘λ„: O(1) - λ³€μˆ˜ 2개만 μ‚¬μš©
63+
"""

β€Žnumber-of-1-bits/unpo88.pyβ€Ž

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class Solution:
2+
def hammingWeight(self, n: int) -> int:
3+
return bin(n).count('1')
4+
5+
6+
"""
7+
================================================================================
8+
풀이 κ³Όμ •
9+
================================================================================
10+
11+
1. 일단 μ΄μ§„λ²•μœΌλ‘œ 변경이 ν•„μš”ν•˜κ³ 
12+
2. λ³€κ²½λœ μ΄μ§„λ²•μ—μ„œ 1을 μΉ΄μš΄νŒ…ν•΄μ•Όν•˜λ„€?
13+
14+
15+
[1μ°¨ μ‹œλ„] λ‚΄μž₯ ν•¨μˆ˜ ν™œμš©
16+
────────────────────────────────────────────────────────────────────────────────
17+
3. Python의 bin() ν•¨μˆ˜λ‘œ 이진 λ¬Έμžμ—΄ λ³€ν™˜
18+
4. count() λ©”μ„œλ“œλ‘œ '1' 문자 개수 μ„ΈκΈ°
19+
20+
return bin(n).count('1')
21+
22+
5. μ‹œκ°„ λ³΅μž‘λ„: O(log n) - 이진 ν‘œν˜„μ˜ λΉ„νŠΈ 수만큼
23+
6. 곡간 λ³΅μž‘λ„: O(log n) - 이진 λ¬Έμžμ—΄ 생성
24+
"""

β€Žvalid-palindrome/unpo88.pyβ€Ž

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
class Solution:
2+
def isPalindrome(self, s: str) -> bool:
3+
left = 0
4+
right = len(s) - 1
5+
6+
while left < right:
7+
if not s[left].isalnum():
8+
left += 1
9+
continue
10+
11+
if not s[right].isalnum():
12+
right -= 1
13+
continue
14+
15+
if s[left].upper() != s[right].upper():
16+
return False
17+
18+
left += 1
19+
right -= 1
20+
21+
return True
22+
23+
24+
"""
25+
================================================================================
26+
풀이 κ³Όμ •
27+
================================================================================
28+
- A man, a plan, a canal: Panama
29+
- λ„μ–΄μ“°κΈ°λŠ” λ¬΄μ‹œν•˜κ³  μ•ž λ’€μ—μ„œ λ˜‘κ°™μ€μ§€ 체크λ₯Ό ν•΄μ•Όν•˜λ„€?
30+
- μ•ž 포인터와 λ’· ν¬μΈν„°μ—μ„œ μ‹œμž‘ν•΄μ„œ 띄어쓰기 λ§Œλ‚˜λ©΄ κ±΄λ„ˆλ›°κ³ 
31+
- 틀린것 λ‚˜μ˜€λ©΄ False λ°˜ν™˜ν•˜κ³ , Falseλ₯Ό λ§Œλ‚œμ  μ—†μœΌλ©΄ True λ°˜ν™˜
32+
33+
[1μ°¨ μ‹œλ„] Two Pointer
34+
────────────────────────────────────────────────────────────────────────────────
35+
1. μ ‘κ·Ό 방법
36+
- Two Pointer μ‚¬μš©: leftλŠ” μ•žμ—μ„œ, rightλŠ” λ’€μ—μ„œ μ‹œμž‘
37+
- μœ νš¨ν•˜μ§€ μ•Šμ€ 문자(μ•ŒνŒŒλ²³/μˆ«μžκ°€ μ•„λ‹Œ 것)λŠ” κ±΄λ„ˆλ›°κΈ°
38+
- μœ νš¨ν•œ 문자끼리 λΉ„κ΅ν•˜λ©° μ€‘μ•™μœΌλ‘œ 이동
39+
40+
2. κ΅¬ν˜„
41+
left = 0
42+
right = len(s) - 1
43+
44+
while left < right:
45+
# μ™Όμͺ½ 포인터: μ•ŒνŒŒλ²³/μˆ«μžκ°€ μ•„λ‹ˆλ©΄ κ±΄λ„ˆλ›°κΈ°
46+
if not s[left].isalpha() and not s[left].isnumeric():
47+
left += 1
48+
continue
49+
50+
# 였λ₯Έμͺ½ 포인터: μ•ŒνŒŒλ²³/μˆ«μžκ°€ μ•„λ‹ˆλ©΄ κ±΄λ„ˆλ›°κΈ°
51+
if not s[right].isalpha() and not s[right].isnumeric():
52+
right -= 1
53+
continue
54+
55+
# λŒ€μ†Œλ¬Έμž λ¬΄μ‹œν•˜κ³  비ꡐ
56+
if s[left].upper() != s[right].upper():
57+
return False
58+
59+
left += 1
60+
right -= 1
61+
62+
return True
63+
64+
4. μ‹œκ°„ λ³΅μž‘λ„: O(n) - λ¬Έμžμ—΄μ„ ν•œ 번만 순회
65+
5. 곡간 λ³΅μž‘λ„: O(1) - μΆ”κ°€ 곡간 μ‚¬μš© μ—†μŒ (포인터 2개만 μ‚¬μš©)
66+
"""

0 commit comments

Comments
Β (0)