-
-
Notifications
You must be signed in to change notification settings - Fork 304
[unpo88] WEEK 03 solutions #2084
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
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
737b202
feat: valid-palindrome 풀이 추가
unpo88 b8b94a3
feat: number-of-1-bits 풀이 추가
unpo88 2db0603
feat: combination-sum 풀이 추가
unpo88 9f8ceb2
feat: maximum-subarray 풀이 추가
unpo88 1b713c4
feat: 줄바꿈 누락 추가
unpo88 e849508
feat: 줄바꿈 누락 추가
unpo88 fade13e
feat: decode-ways 풀이 추가
unpo88 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| class Solution: | ||
| def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: | ||
| result = [] | ||
|
|
||
| def backtrack(start, current, current_sum): | ||
| if current_sum == target: | ||
| result.append(current[:]) | ||
| return | ||
|
|
||
| if current_sum > target: | ||
| return | ||
|
|
||
| for i in range(start, len(candidates)): | ||
| current.append(candidates[i]) | ||
| backtrack(i, current, current_sum + candidates[i]) | ||
| current.pop() | ||
|
|
||
| backtrack(0, [], 0) | ||
| return result | ||
|
|
||
|
|
||
| """ | ||
| ================================================================================ | ||
| 풀이 과정 | ||
| ================================================================================ | ||
|
|
||
| 1. 이거 모든 가능한 조합을 찾아야하는데 합이 target을 넘으면 중단되야하네? | ||
| 2. 문제는 같은 숫자를 여러 번 쓸 수 있는건데.. | ||
| 3. 백트래킹으로 접근해야할 것 같은데.. | ||
|
|
||
|
|
||
| [1차 시도] 백트래킹 (Backtracking) | ||
| ──────────────────────────────────────────────────────────────────────────────── | ||
| 4. 모든 조합을 탐색하되, 조건에 맞지 않으면 가지치기 | ||
| 5. 같은 숫자를 여러 번 사용할 수 있으므로 재귀 호출 시 같은 인덱스부터 시작 | ||
| 6. 중복 조합 방지를 위해 start 인덱스 사용 | ||
|
|
||
| result = [] | ||
|
|
||
| def backtrack(start, current, current_sum): | ||
| # target을 만족하면 결과에 추가 | ||
| if current_sum == target: | ||
| result.append(current[:]) # 복사해서 추가 | ||
| return | ||
|
|
||
| # 가지치기: 합이 target 초과 | ||
| if current_sum > target: | ||
| return | ||
|
|
||
| # 조합 탐색 | ||
| for i in range(start, len(candidates)): | ||
| current.append(candidates[i]) | ||
| # 같은 숫자 재사용 가능하므로 i부터 시작 | ||
| backtrack(i, current, current_sum + candidates[i]) | ||
| current.pop() # 백트래킹: 상태 복원 | ||
|
|
||
| backtrack(0, [], 0) | ||
| return result | ||
|
|
||
| 7. Example: candidates = [2,3,6,7], target = 7 | ||
|
|
||
| backtrack(0, [], 0) | ||
| ├─ 2 추가 → backtrack(0, [2], 2) | ||
| │ ├─ 2 추가 → backtrack(0, [2,2], 4) | ||
| │ │ ├─ 2 추가 → backtrack(0, [2,2,2], 6) | ||
| │ │ │ └─ 2 추가 → backtrack(0, [2,2,2,2], 8) → 8 > 7 return | ||
| │ │ └─ 3 추가 → backtrack(1, [2,2,3], 7) → 7 == 7 ✅ [2,2,3] | ||
| │ └─ 3 추가 → backtrack(1, [2,3], 5) | ||
| │ └─ ... (탐색 계속) | ||
| └─ 7 추가 → backtrack(3, [7], 7) → 7 == 7 ✅ [7] | ||
|
|
||
| 8. 시간 복잡도: O(N^(T/M)) | ||
| - N: candidates 길이 | ||
| - T: target 값 | ||
| - M: candidates의 최소값 | ||
| 9. 공간 복잡도: O(T/M) - 재귀 호출 스택 깊이 | ||
| """ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| class Solution: | ||
| def numDecodings(self, s: str) -> int: | ||
| # 예외 처리: "0"으로 시작하면 불가능 | ||
| if not s or s[0] == '0': | ||
| return 0 | ||
|
|
||
| n = len(s) | ||
| dp = [0] * (n + 1) | ||
|
|
||
| # 초기값 | ||
| dp[0] = 1 # 빈 문자열 | ||
| dp[1] = 1 # 첫 번째 문자 (이미 "0" 체크함) | ||
|
|
||
| for i in range(2, n + 1): | ||
| # 한 자리 숫자 (1~9) | ||
| if s[i-1] != '0': | ||
| dp[i] += dp[i-1] | ||
|
|
||
| # 두 자리 숫자 (10~26) | ||
| two_digit = int(s[i-2:i]) | ||
| if 10 <= two_digit <= 26: | ||
| dp[i] += dp[i-2] | ||
|
|
||
| return dp[n] | ||
|
|
||
|
|
||
| """ | ||
| ================================================================================ | ||
| 풀이 과정 | ||
| ================================================================================ | ||
| - "226" → 2|2|6 (BBF), 22|6 (VF), 2|26 (BZ) → 3가지 방법 존재 | ||
| - DP를 이용해서 각 위치에서 가능한 디코딩 경우의 수를 계산 | ||
| - 한 자리(1~9)와 두 자리(10~26) 숫자를 고려하여 누적 | ||
|
|
||
| [1차 시도] | ||
| ──────────────────────────────────────────────────────────────────────────────── | ||
| 1. 접근 방법 | ||
| - DP 배열 사용: dp[i] = 문자열의 처음부터 i번째까지의 디코딩 경우의 수 | ||
| - 각 위치에서 한 자리 숫자(1~9)로 디코딩 가능하면 dp[i-1] 더하기 | ||
| - 두 자리 숫자(10~26)로 디코딩 가능하면 dp[i-2] 더하기 | ||
|
|
||
| 2. 구현 | ||
| n = len(s) | ||
| dp = [0] * (n + 1) | ||
|
|
||
| # 초기값 설정 | ||
| dp[0] = 1 # 빈 문자열 | ||
| dp[1] = 1 # 첫 번째 문자 (0이 아니면 1가지) | ||
|
|
||
| for i in range(2, n + 1): | ||
| # 한 자리 숫자 (1~9) | ||
| if s[i-1] != '0': | ||
| dp[i] += dp[i-1] | ||
|
|
||
| # 두 자리 숫자 (10~26) | ||
| two_digit = int(s[i-2:i]) | ||
| if 10 <= two_digit <= 26: | ||
| dp[i] += dp[i-2] | ||
|
|
||
| 3. 예외 처리 | ||
| - "0"으로 시작하는 문자열은 디코딩 불가능 → 0 반환 | ||
| - 빈 문자열 체크 | ||
|
|
||
| 4. 시간 복잡도: O(n) - 문자열을 한 번만 순회 | ||
| 5. 공간 복잡도: O(n) - DP 배열 사용 | ||
| """ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| class Solution: | ||
| def maxSubArray(self, nums: List[int]) -> int: | ||
| current_sum = nums[0] | ||
| max_sum = nums[0] | ||
|
|
||
| for i in range(1, len(nums)): | ||
| # 현재 값부터 새로 시작 vs 이전 합에 추가 | ||
| current_sum = max(nums[i], current_sum + nums[i]) | ||
| max_sum = max(max_sum, current_sum) | ||
|
|
||
| return max_sum | ||
|
|
||
|
|
||
| """ | ||
| ================================================================================ | ||
| 풀이 과정 | ||
| ================================================================================ | ||
|
|
||
| 1. 부분 배열 중 가장 큰 합을 찾아야 하는데 어떻게 접근하지? | ||
| 2. Sliding Window? → 음수/양수가 섞여있어서 윈도우 크기를 언제 조절할지 불명확 | ||
| 3. 모든 부분배열을 확인? → O(n²)이라 비효율적 | ||
| 4. 각 위치에서 "현재까지의 최대 부분합"을 추적하면 되지 않을까? | ||
|
|
||
|
|
||
| [1차 시도] Dynamic Programming | ||
| ──────────────────────────────────────────────────────────────────────────────── | ||
| 5. 핵심 아이디어: 각 위치에서 "이 위치를 끝으로 하는" 최대 부분배열의 합 추적 | ||
| 6. current_sum = "현재 위치를 끝으로 하는 최대 부분합" | ||
| 7. 매 위치에서 선택: 이전 합에 추가 vs 여기서 새로 시작 | ||
|
|
||
| current_sum = nums[0] # 현재 위치까지의 최대 부분합 | ||
| max_sum = nums[0] # 전체 최댓값 | ||
|
|
||
| for i in range(1, len(nums)): | ||
| # 이전 합이 양수면 계속, 음수면 버리고 새로 시작 | ||
| current_sum = max(nums[i], current_sum + nums[i]) | ||
| max_sum = max(max_sum, current_sum) | ||
|
|
||
| return max_sum | ||
|
|
||
| 8. Example: nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4] | ||
|
|
||
| i=0: current=-2, max=-2 | ||
| i=1: max(1, -2+1=-1) = 1 (새로 시작), max=1 | ||
| i=2: max(-3, 1-3=-2) = -2 (이어감), max=1 | ||
| i=3: max(4, -2+4=2) = 4 (새로 시작), max=4 | ||
| i=4: max(-1, 4-1=3) = 3 (이어감), max=4 | ||
| i=5: max(2, 3+2=5) = 5 (이어감), max=5 | ||
| i=6: max(1, 5+1=6) = 6 (이어감), max=6 ✓ | ||
| i=7: max(-5, 6-5=1) = 1 (이어감), max=6 | ||
| i=8: max(4, 1+4=5) = 5 (이어감), max=6 | ||
|
|
||
| 결과: [4, -1, 2, 1] = 6 | ||
|
|
||
| 9. 왜 작동하는가? | ||
| - 모든 부분배열은 어딘가에서 끝남 | ||
| - 각 위치에서 "여기를 끝으로 하는 최댓값" 추적 | ||
| - 이전 합이 음수면 버리는 게 이득 (Greedy한 선택) | ||
| - 이전 합이 양수면 현재 값이 음수여도 계속 (예: 4 + (-1) = 3) | ||
|
|
||
| 10. 시간 복잡도: O(n) - 배열을 한 번만 순회 | ||
| 11. 공간 복잡도: O(1) - 변수 2개만 사용 | ||
| """ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| class Solution: | ||
| def hammingWeight(self, n: int) -> int: | ||
| return bin(n).count('1') | ||
|
|
||
|
|
||
| """ | ||
| ================================================================================ | ||
| 풀이 과정 | ||
| ================================================================================ | ||
|
|
||
| 1. 일단 이진법으로 변경이 필요하고 | ||
| 2. 변경된 이진법에서 1을 카운팅해야하네? | ||
|
|
||
|
|
||
| [1차 시도] 내장 함수 활용 | ||
| ──────────────────────────────────────────────────────────────────────────────── | ||
| 3. Python의 bin() 함수로 이진 문자열 변환 | ||
| 4. count() 메서드로 '1' 문자 개수 세기 | ||
|
|
||
| return bin(n).count('1') | ||
|
|
||
| 5. 시간 복잡도: O(log n) - 이진 표현의 비트 수만큼 | ||
| 6. 공간 복잡도: O(log n) - 이진 문자열 생성 | ||
| """ |
8804who marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| class Solution: | ||
| def isPalindrome(self, s: str) -> bool: | ||
| left = 0 | ||
| right = len(s) - 1 | ||
|
|
||
| while left < right: | ||
| if not s[left].isalnum(): | ||
| left += 1 | ||
| continue | ||
|
|
||
| if not s[right].isalnum(): | ||
| right -= 1 | ||
| continue | ||
|
|
||
| if s[left].upper() != s[right].upper(): | ||
| return False | ||
|
|
||
| left += 1 | ||
| right -= 1 | ||
|
|
||
| return True | ||
|
|
||
|
|
||
| """ | ||
| ================================================================================ | ||
| 풀이 과정 | ||
| ================================================================================ | ||
| - A man, a plan, a canal: Panama | ||
| - 띄어쓰기는 무시하고 앞 뒤에서 똑같은지 체크를 해야하네? | ||
| - 앞 포인터와 뒷 포인터에서 시작해서 띄어쓰기 만나면 건너뛰고 | ||
| - 틀린것 나오면 False 반환하고, False를 만난적 없으면 True 반환 | ||
|
|
||
| [1차 시도] Two Pointer | ||
| ──────────────────────────────────────────────────────────────────────────────── | ||
| 1. 접근 방법 | ||
| - Two Pointer 사용: left는 앞에서, right는 뒤에서 시작 | ||
| - 유효하지 않은 문자(알파벳/숫자가 아닌 것)는 건너뛰기 | ||
| - 유효한 문자끼리 비교하며 중앙으로 이동 | ||
|
|
||
| 2. 구현 | ||
| left = 0 | ||
| right = len(s) - 1 | ||
|
|
||
| while left < right: | ||
| # 왼쪽 포인터: 알파벳/숫자가 아니면 건너뛰기 | ||
| if not s[left].isalpha() and not s[left].isnumeric(): | ||
| left += 1 | ||
| continue | ||
|
|
||
| # 오른쪽 포인터: 알파벳/숫자가 아니면 건너뛰기 | ||
| if not s[right].isalpha() and not s[right].isnumeric(): | ||
| right -= 1 | ||
| continue | ||
|
|
||
| # 대소문자 무시하고 비교 | ||
| if s[left].upper() != s[right].upper(): | ||
| return False | ||
|
|
||
| left += 1 | ||
| right -= 1 | ||
|
|
||
| return True | ||
|
|
||
| 4. 시간 복잡도: O(n) - 문자열을 한 번만 순회 | ||
| 5. 공간 복잡도: O(1) - 추가 공간 사용 없음 (포인터 2개만 사용) | ||
| """ |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.