[alphaorderly] WEEK 07 Solutions - #2793
Conversation
๐ alphaorderly ๋์ ํ์ต ํํฉ์ด๋ฒ ์ฃผ ์ ์ถ ๋ฌธ์
๋์ ํ์ต ์์ฝ
๋ฌธ์ ํ์ด ํํฉ
๐ค ์ด ๋๊ธ์ GitHub App์ ํตํด ์๋์ผ๋ก ์์ฑ๋์์ต๋๋ค. ๐ข API ์ฌ์ฉ๋ (gpt-5-nano)
|
There was a problem hiding this comment.
2D DP์์ dp ๋ด์ฉ์ ์ถ๋ ฅํ๊ณ
๋๊ฐ์ ์ผ๋ก ๋ณด๋ฉด Pascal Triangle์ด ๋ง๋ค์ด์ง๋๋ค.
์ด๊ฒ๋๋ก Combination ์ฐ์ฐ์ผ๋ก ํ์
๋ ๋งจ ์๋ ์ฝ๋๋ฅผ ์ป์์ ์์ผ์ธ์!
There was a problem hiding this comment.
๐ท๏ธ ์๊ณ ๋ฆฌ์ฆ ํจํด ๋ถ์
- ํจํด: Sliding Window, Hash Map / Hash Set
- ์ค๋ช : ๋ ํฌ์ธํฐ(left, right)๋ก ์ฐ์ ๋ถ๋ถ ๋ฌธ์์ด์ ์ฐฝ/window๋ก ํ์ฅ ์ถ์ํ๋ฉฐ ์๋ก ๋ค๋ฅธ ๋ฌธ์๋ง ๋จ๋๋ก ์ค๋ณต ์ฌ๋ถ๋ฅผ ํด์ ๋งต์ผ๋ก ๊ด๋ฆฌํ๋ ๋ฐฉ์์ด๋ค. ์ด๋ ๊ธธ์ด๊ฐ ์ต๋๋ก ๋๋ ๋ชจ๋ ๊ณ ์ ๋ถ๋ถ ๋ฌธ์์ด์ ์ฐพ๋ ์ผ๋ฐ์ ์ธ Sliding Window ํจํด์ ํด๋นํ๋ค.
๐ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋ ๋ถ์
| ๋ณต์ก๋ | |
|---|---|
| Time | O(n) |
| Space | O(n) |
ํผ๋๋ฐฑ: ์ฌ๋ผ์ด๋ฉ ์๋์ฐ์ ํด์๋งต(๋์ ๋๋ฆฌ) ํ์ฉ์ผ๋ก ๊ฐ ๋ฌธ์ ๋ฑ์ฅ ์ฌ๋ถ๋ฅผ ๊ด๋ฆฌํ๋ค. right ์ฆ๊ฐ์ ๋ฐ๋ผ ์ค๋ณต์ด ์๊ธฐ๋ฉด left๋ฅผ ์ด๋์ํค๋ฉฐ ์๋์ฐ ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ๋ค.
๊ฐ์ ์ ์: ํ์ฌ ๊ตฌํ์ด ์ ์ ํด ๋ณด์ ๋๋ค.
๐ก ํ์ด์ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋๋ฅผ ์ฃผ์์ผ๋ก ๋จ๊ฒจ๋ณด์ธ์!
There was a problem hiding this comment.
๐ท๏ธ ์๊ณ ๋ฆฌ์ฆ ํจํด ๋ถ์
- ํจํด: Depth-First Search, Breadth-First Search, Hash Map / Hash Set
- ์ค๋ช : ์ฝ๋๋ BFS์ DFS ๋ ๊ฐ์ง ๋ฐฉ์์ผ๋ก ์ฌ์ ํ์ํ๋ฉฐ, ๋ฐฉ๋ฌธ ์ฌ๋ถ๋ฅผ ํ์ํ๊ธฐ ์ํด ๊ฒฉ์ ๋ฐ์ดํฐ๋ฅผ '#''๋ก ๋ฐ๊ฟ๋๋ค. ๋ ๊ตฌํ ๋ชจ๋ ์ธ์ ํ ๋ ์ ํ์ํ๊ณ ์ฌ์ ์๋ฅผ ์ฆ๊ฐ์ํค๋ ํจํด์ ๋ณด์ด๋ฉฐ, ๋ฐฉ๋ฌธ ๊ด๋ฆฌ์ ์ถ๊ฐ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ์ง ์๋ ์ ์์ ํด์ ๋งต/์ธํธ์ ์ง์ ์ฌ์ฉ์ ๋ณด์กฐ์ ์ผ๋ก ํ๋จ๋ฉ๋๋ค.
๐ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋ ๋ถ์
โน๏ธ ์ด ํ์ผ์๋ 2๊ฐ์ง ํ์ด๊ฐ ํฌํจ๋์ด ์์ด ๊ฐ๊ฐ ๋ถ์ํฉ๋๋ค.
ํ์ด 1: Solution.numIslands โ Time: O(m * n) / Space: O(m * n)
| ๋ณต์ก๋ | |
|---|---|
| Time | O(m * n) |
| Space | O(m * n) |
ํผ๋๋ฐฑ: ๋ ๊ฐ์ง ๊ตฌํ์ด ์ ์๋์ด ์์ผ๋ฉฐ ๋ชจ๋ ํ์์ผ๋ก ๋ชจ๋ ์ก์ง('1')๋ฅผ ๋ฐฉ๋ฌธํ๋ค. ๋ฐฉ๋ฌธ ์ฌ๋ถ๋ฅผ ํ์ํ๊ธฐ ์ํด grid๋ฅผ ๋ณํํ์ฌ ์ถ๊ฐ ๊ณต๊ฐ์ ์ฌ์ฉํ์ง ์๋๋ค.
๊ฐ์ ์ ์: ํ์ฌ ๊ตฌํ์ด ์ ์ ํด ๋ณด์ ๋๋ค.
ํ์ด 2: Solution.numIslands โ Time: O(m * n) / Space: O(m * n)
| ๋ณต์ก๋ | |
|---|---|
| Time | O(m * n) |
| Space | O(m * n) |
ํผ๋๋ฐฑ: ์ฌ๊ท๋ฅผ ์ด์ฉํ DFS๋ก ๋ชจ๋ ์ฐ๊ฒฐ๋ ์ก์ง๋ฅผ ํ์ํ๋ค. ์คํ์ ์ฌ์ฉํ๋ ๊ตฌํ๊ณผ ๋์ผํ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋๋ค.
๊ฐ์ ์ ์: ํ์ฌ ๊ตฌํ์ด ์ ์ ํด ๋ณด์ ๋๋ค.
๐ก ํ์ด์ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋๋ฅผ ์ฃผ์์ผ๋ก ๋จ๊ฒจ๋ณด์ธ์!
There was a problem hiding this comment.
๐ท๏ธ ์๊ณ ๋ฆฌ์ฆ ํจํด ๋ถ์
- ํจํด: Two Pointers, Linked List
- ์ค๋ช : ํค๋์ ํ๋ฆฌ๋ธ ํฌ์ธํฐ๋ฅผ ์ด์ฉํด linked list๋ฅผ ์ญ์์ผ๋ก ์ํํ๋ฉฐ ๋ ธ๋ ์ฐ๊ฒฐ์ ์ฌ์ค์ ํ๋ ์ ํ์ ์ธ ํฌ ํฌ์ธํฐ ๊ธฐ๋ฒ. ๊ณต๊ฐ ๋ณต์ก๋ O(1), ๋ฐ๋ณต ๊ตฌ์กฐ๋ก ๋ฆฌ์คํธ๋ฅผ ํ ๋ฒ ์ํํ๋ค.
๐ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋ ๋ถ์
| ๋ณต์ก๋ | |
|---|---|
| Time | O(n) |
| Space | O(1) |
ํผ๋๋ฐฑ: ๋จ์ผ ํฌ์ธํฐ๋ฅผ ํ์ฉํด ์ ๋ ธ๋์ ํ์ฌ ๋ ธ๋์ ์ฐ๊ฒฐ์ ์ญ์ ํ๋ค.
๊ฐ์ ์ ์: ํ์ฌ ๊ตฌํ์ด ์ ์ ํด ๋ณด์ ๋๋ค.
๐ก ํ์ด์ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋๋ฅผ ์ฃผ์์ผ๋ก ๋จ๊ฒจ๋ณด์ธ์!
There was a problem hiding this comment.
๐ท๏ธ ์๊ณ ๋ฆฌ์ฆ ํจํด ๋ถ์
- ํจํด: Dynamic Programming, Greedy, Hash Map / Hash Set
- ์ค๋ช : ์ด ์ฝ๋๋ ํ/์ด์ ํ๋๊ทธ๋ฅผ ์ฒซ ํ/์ด์ ์์ ์ ์ฅ์๋ก ํ์ฉํ๋ ๋ฐฉ์์ผ๋ก ์ ๋ก๋ฅผ ํ์ํ๋ ํจํด์ด๋ค. ๊ณต๊ฐ์ ์ถ๊ฐ๋ก ์ฌ์ฉํ์ง ์๊ณ ์๋ ๋ฐฐ์ด์ ํ/์ด์ ์ด์ฉํด ์กฐ๊ฑด์ ์ ํํ๋ฏ๋ก ์ผ๋ฐ์ ์ผ๋ก ์ต์ ํ๋ ํ์/ํ์ ๊ธฐ๋ฒ์ผ๋ก ๋ถ๋ฅ๋๋ค.
๐ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋ ๋ถ์
| ๋ณต์ก๋ | |
|---|---|
| Time | O(m * n) |
| Space | O(1) |
ํผ๋๋ฐฑ: ์ฒซ ํ/์ด์ ๋ง์ปค๋ก ํ์ฉํ๋ ํ์ค ์ต์ ํ ๋ฐฉ๋ฒ์ ํํ๋ค. ์ด๊ธฐ ์ํ๋ฅผ ๋ฐ๋ก ํ์ธํ์ฌ ๊ฒฝ๊ณ ์ผ์ด์ค๋ฅผ ์ฒ๋ฆฌํ๋ค.
๊ฐ์ ์ ์: ํ์ฌ ๊ตฌํ์ด ์ ์ ํด ๋ณด์ ๋๋ค.
๐ก ํ์ด์ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋๋ฅผ ์ฃผ์์ผ๋ก ๋จ๊ฒจ๋ณด์ธ์!
There was a problem hiding this comment.
๐ท๏ธ ์๊ณ ๋ฆฌ์ฆ ํจํด ๋ถ์
- ํจํด: Dynamic Programming, Combinatorial, Memoization
- ์ค๋ช : ๋ค์ํ ๊ตฌํ์์ 2D/1D DP๋ฅผ ์ด์ฉํ ์ต๋จ ๊ฒฝ๋ก์ ๊ฒฝ์ฐ์ ์๋ฅผ ๊ณ์ฐํ๊ณ , ์ฌ๊ท+์บ์(๋ฉ๋ชจ์ด์ ์ด์ ) ํจํด์ผ๋ก ์ค๋ณต ๊ณ์ฐ์ ์ค์ด๋ ์ฌ๋ก๊ฐ ํฌํจ๋์ด ์์ต๋๋ค. ๋ํ ์ฌ๊ท ๊ธฐ๋ฐ์ ์ํฅ์ DP๋ฅผ ๋ณด์ํ๋ memoization ๊ธฐ๋ฒ์ด ์ฌ์ฉ๋ฉ๋๋ค.
๐ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋ ๋ถ์
โน๏ธ ์ด ํ์ผ์๋ 4๊ฐ์ง ํ์ด๊ฐ ํฌํจ๋์ด ์์ด ๊ฐ๊ฐ ๋ถ์ํฉ๋๋ค.
ํ์ด 1: Solution.uniquePaths โ Time: O(m * n) / Space: O(m * n)
| ๋ณต์ก๋ | |
|---|---|
| Time | O(m * n) |
| Space | O(m * n) |
ํผ๋๋ฐฑ: ์ฌ๋ฌ ์ ๊ทผ ๋ฐฉ์์ด ํฌํจ๋์ด ์์ง๋ง ๊ฐ๊ฐ์ ๊ตฌํ์ ์๋ก ๋ค๋ฅธ ๊ณต๊ฐ/์๊ฐ ํน์ฑ์ ๊ฐ์ง๋ค. ๋ฌธ์ ์ ๋ฐ๋ผ ์ ํ์ ์ผ๋ก ์ฌ์ฉํ ์ ์๋ค.
๊ฐ์ ์ ์: ํ์ฌ ๊ตฌํ์ด ์ ์ ํด ๋ณด์ ๋๋ค.
ํ์ด 2: Solution.uniquePaths โ Time: O(m * n) / Space: O(n)
| ๋ณต์ก๋ | |
|---|---|
| Time | O(m * n) |
| Space | O(n) |
ํผ๋๋ฐฑ: ํ๋ง๋ค ์ด์ ๊ฒฝ๋ก๋ฅผ ๋์ ์ ๋ฐ์ดํธํ์ฌ ๊ณต๊ฐ์ ์ค์ธ๋ค.
๊ฐ์ ์ ์: ํ์ฌ ๊ตฌํ์ด ์ ์ ํด ๋ณด์ ๋๋ค.
ํ์ด 3: Solution.uniquePaths โ Time: O(1) / Space: O(1)
| ๋ณต์ก๋ | |
|---|---|
| Time | O(1) |
| Space | O(1) |
ํผ๋๋ฐฑ: ํฉํ ๋ฆฌ์ผ ๊ธฐ๋ฐ์ ์กฐํฉ ๊ณ์ฐ์ผ๋ก ์๊ฐ ๋ณต์ก๋๋ ์ ๋ ฅ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง์ง๋ง ์ผ๋ฐ์ ์ผ๋ก ์์ ๊ณ์์ ์ฐจ์ด๊ฐ ์๋ค.
๊ฐ์ ์ ์: ํ์ฌ ๊ตฌํ์ด ์ ์ ํด ๋ณด์ ๋๋ค.
ํ์ด 4: Solution.uniquePaths โ Time: O(m * n) / Space: O(m * n)
| ๋ณต์ก๋ | |
|---|---|
| Time | O(m * n) |
| Space | O(m * n) |
ํผ๋๋ฐฑ: ์ฌ๊ท ๊ธฐ๋ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ์ค๋ณต๋๋ ๋ถ๋ถ ๋ฌธ์ ๋ฅผ ์ ์ฅํด ํจ์จ์ ์ ์งํ๋ค.
๊ฐ์ ์ ์: ํ์ฌ ๊ตฌํ์ด ์ ์ ํด ๋ณด์ ๋๋ค.
๐ก ํ์ด์ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋๋ฅผ ์ฃผ์์ผ๋ก ๋จ๊ฒจ๋ณด์ธ์!
parkhojeong
left a comment
There was a problem hiding this comment.
์๊ณ ํ์ จ์ต๋๋ค. ํ์ด์ ๊ด๊ณ ์๋ ์ปค๋ฐ์ ์ ๋ฆฌ ๋ถํ๋๋ฆฝ๋๋ค.
| while count[val] > 1: | ||
| count[s[left]] -= 1 | ||
| left += 1 |
There was a problem hiding this comment.
left๋ฅผ ํ๋์ฉ ์ฎ๊ธฐ์ง ์๊ณ ์ค๋ณต๋๋ ์ธ๋ฑ์ค ๋ฐ๋ก ๋ค์์ผ๋ก ์ฎ๊ฒจ์ฃผ๋ ๋ฐฉ์์ผ๋ก ์ต์ ํ ํด๋ณผ ์ ์์ ๊ฑฐ ๊ฐ๋ค์
| row_check = any(matrix[0][c] == 0 for c in range(COL)) | ||
| col_check = any(matrix[r][0] == 0 for r in range(ROW)) |
There was a problem hiding this comment.
row_check, col_check๊ฐ ์ด๋ค ์๋ฏธ์ธ์ง ์๊ธฐ๋ ์ด๋ ค์ด ๊ฑฐ ๊ฐ์์ ์ ์ ํ ๋ค์ด๋ฐ ํด์ฃผ์๋ฉด ์ข์ ๊ฑฐ ๊ฐ์ต๋๋ค.
| class Solution: | ||
| def uniquePaths(self, m: int, n: int) -> int: | ||
| return comb(m + n - 2, n - 1) |
There was a problem hiding this comment.
์ค ์ด๋ ๊ฒ๋ ํ ์ ์๊ตฐ์. ํจํด์ด ์๋ ๊ฑฐ ๊ฐ์ ๋ณด์ด๊ธด ํ๋๋ฐ ์์ ๋์ถ์ด ์ ์๋๋๋ผ๊ตฌ์. ์ด๋ฐ ํ์ด ์์ด๋์ด๋ ์ด๋ป๊ฒ ์ป์ผ์ จ๋์ง ๊ถ๊ธํ๋ค์.
| while head: | ||
| prev, head.next, head = head, prev, head.next |
There was a problem hiding this comment.
์ฒซ ๋ ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋ head๊ฐ ์ํํ๋ ๋ ธ๋๋ก ์ฌ์ฉ๋์ด์ ์ค์ ๋ก๋ ๋ ๊ฐ์ง ์๋ฏธ๋ฅผ ๊ฐ์ง๋ ๊ฑฐ ๊ฐ์ต๋๋ค. ์ํ ์ค์ธ ๋ ธ๋๋ฅผ ์ํ ๋ณ๋์ ๋ณ์๋ฅผ ์ฌ์ฉํ๋๊ฒ ์ด๋จ๊น์?
There was a problem hiding this comment.
๐ท๏ธ ์๊ณ ๋ฆฌ์ฆ ํจํด ๋ถ์
longest-substring-without-repeating-characters/alphaorderly.py
"""
Time Complexity: O(n)
Space Complexity: O(n)
Approach:
- Use a defaultdict to track the count of each character in the current window.
- Maintain two pointers, 'left' and 'right', to represent the sliding window over the string.
- As we iterate over the string with 'right', increment the count for the current character.
- If a duplicate character appears in the window (count > 1), move the 'left' pointer forward and decrement counts until there are no duplicates.
- After adjusting, update 'ans' with the maximum length found for a window with all unique characters.
"""
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
count = defaultdict(int)
ans = left = 0
for right, val in enumerate(s):
count[val] += 1
while count[val] > 1:
count[s[left]] -= 1
left += 1
ans = max(ans, right - left + 1)
return ans- ํจํด: Sliding Window, Hash Map / Hash Set
- ์ค๋ช : ๋ ํฌ์ธํฐ(left, right)๋ก ๋ถ๋ถ ๋ฌธ์์ด ์ฐฝ์ ํ์ฅ/์ถ์ํ๋ฉฐ ์ค๋ณต ๋ฌธ์๋ฅผ ํด์ ๋งต์ผ๋ก ์ถ์ ํ๋ค. ์ค๋ณต ๋ฐ์ ์ ์ฐฝ์ ์ข์ธก์ผ๋ก ์ขํ ๊ธธ์ด๊ฐ ์๋ก ๋ค๋ฅธ ๋ถ๋ถ ๋ฌธ์์ด์ ์ต๋ ๊ธธ์ด๋ฅผ ๊ตฌํ๋ค.
๐ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋ ๋ถ์
| ๋ณต์ก๋ | |
|---|---|
| Time | O(n) |
| Space | O(n) |
ํผ๋๋ฐฑ: ํ์ฌ ๊ตฌํ์ ํฌ ํฌ์ธํฐ์ ํด์๋งต์ผ๋ก ๋ชจ๋ ๋ฌธ์๋ฅผ ํ ๋ฒ์ฉ ๋ฐฉ๋ฌธํ๋ฏ๋ก ์ต์ ์ ๊ฒฝ์ฐ ์ ํ ์๊ฐ๊ณผ ์ ํ ๊ณต๊ฐ์ด ํ์ํฉ๋๋ค.
๊ฐ์ ์ ์: ๊ณ ๋ คํด๋ณผ ๋งํ ๋์: ์นด์ดํธ ๋์ ์ธ๋ฑ์ค ์ ์ฅ ๋ฐฉ์์ผ๋ก ๊ตฌํํ๋ฉด ๋ถํ์ํ ์นด์ดํธ๋ฅผ ์ค์ด๊ณ , ๋์ ๋๋ฆฌ ๋์ ๋ฐฐ์ด ๊ธฐ๋ฐ ์ธ๋ฑ์ค ๋งคํ์ ์ฌ์ฉํด ์์ ๊ณต๊ฐ์ ๊ฐ๊น๊ฒ ์ต์ ํ ๊ฐ๋ฅ.
๐ก ํ์ด์ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋๋ฅผ ์ฃผ์์ผ๋ก ๋จ๊ฒจ๋ณด์ธ์!
There was a problem hiding this comment.
๐ท๏ธ ์๊ณ ๋ฆฌ์ฆ ํจํด ๋ถ์
number-of-islands/alphaorderly.py
"""
Time Complexity: O(m * n)
Space Complexity: O(m * n)
### BFS Approach ###
Approach:
- Use BFS to traverse all parts of each island in the grid.
- Employ a queue to process all adjacent land cells iteratively.
- Use a 'bound' helper function to check if a cell is within the grid bounds.
- In 'island_marker', mark visited '1's with '#' to avoid revisiting.
- For every cell in the grid, when a land cell ('1') is encountered, initiate BFS and increment the island count.
"""
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
DIR = [[0, 1], [1, 0], [-1, 0], [0, -1]]
ROW = len(grid)
COL = len(grid[0])
def bound(row: int, col: int) -> bool:
return 0 <= row < ROW and 0 <= col < COL
def island_marker(row: int, col: int) -> None:
q = deque([(row, col)])
grid[row][col] = "#"
while q:
r, c = q.popleft()
for dr, dc in DIR:
tr, tc = r + dr, c + dc
if not bound(tr, tc) or grid[tr][tc] != "1":
continue
grid[tr][tc] = "#"
q.append((tr, tc))
ans = 0
for r in range(ROW):
for c in range(COL):
if grid[r][c] == "1":
island_marker(r, c)
ans += 1
return ans
"""
Time Complexity: O(m * n)
Space Complexity: O(m * n)
### DFS Approach ###
Approach:
- Use DFS to traverse all parts of each island in the grid.
- Visitation is done recursively rather than with a stack, so stack comment is removed for clarity.
- Use a 'bound' helper function to check if a cell is within the grid bounds.
- In 'island_marker', mark visited '1's with '#' to avoid revisiting.
- For every cell in the grid, when a land cell ('1') is encountered, initiate DFS and increment the island count.
"""
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
DIR = [[0, 1], [1, 0], [-1, 0], [0, -1]]
ROW = len(grid)
COL = len(grid[0])
def bound(row: int, col: int) -> bool:
return 0 <= row < ROW and 0 <= col < COL
def island_marker(row: int, col: int) -> None:
grid[row][col] = '#'
for dr, dc in DIR:
tr, tc = row + dr, col + dc
if bound(tr, tc) and grid[tr][tc] == '1':
island_marker(tr, tc)
ans = 0
for r in range(ROW):
for c in range(COL):
if grid[r][c] == "1":
island_marker(r, c)
ans += 1
return ans- ํจํด: Depth-First Search, Breadth-First Search, Hash Map / Hash Set
- ์ค๋ช : ์ฝ๋์์ ์ฌ์ ๋ชจ์๋๋ก ํ์ํ๋ฉฐ ์ธ์ ํ ๋ ์ ๋ฐฉ๋ฌธ ์ฒ๋ฆฌํ๋ค. DFS ๊ตฌํ์ ์ฌ๊ท๋ก, BFS ๊ตฌํ์ ํ๋ก ๋๋น ์ฐ์ ํ์์ ์ด์ฉํ๋ค. ๋ฐฉ๋ฌธ ์ฌ๋ถ๋ '#''๋ก ๋งํนํ๋ ๋ฐฉ์์ผ๋ก ๊ด๋ฆฌ๋๋ฉฐ, ๊ฐ์ ์์๋ฅผ ๋ค์ ๋ฐฉ๋ฌธํ์ง ์๋๋ค.
๐ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋ ๋ถ์
| ๋ณต์ก๋ | |
|---|---|
| Time | O(m * n) |
| Space | O(m * n) |
ํผ๋๋ฐฑ: ๋ ๊ฐ์ง ๊ตฌํ์ด ์ ์๋์๊ณ , ๋ ๋ค ์ ์ฒด ๊ฒฉ์๋ฅผ ํ ๋ฒ ์ด์ ํ์ํฉ๋๋ค. ์ถ๊ฐ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ์ BFS๊ฐ ํฐ ์ฐจ์ง์ ๋๋ค.
๊ฐ์ ์ ์: ํ์ฌ ๊ตฌํ์ด ์ ์ ํด ๋ณด์ ๋๋ค.
๐ก ํ์ด์ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋๋ฅผ ์ฃผ์์ผ๋ก ๋จ๊ฒจ๋ณด์ธ์!
There was a problem hiding this comment.
๐ท๏ธ ์๊ณ ๋ฆฌ์ฆ ํจํด ๋ถ์
reverse-linked-list/alphaorderly.py
"""
Time Complexity: O(n)
Space Complexity: O(1)
- We use a while loop to traverse the linked list.
- We use a prev pointer to store the previous node.
- We use a head pointer to store the current node.
- We use a old_next pointer to store the next node.
- We use a prev, head = head, old_next to update the prev and head pointers.
- We return the prev pointer.
"""
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
prev = None
while head:
prev, head.next, head = head, prev, head.next
return prev- ํจํด: Two Pointers, Linked List, Greedy, Dynamic Programming
- ์ค๋ช : ํค๋์ ํ๋ฆฌ๋ธ ํฌ์ธํฐ๋ฅผ ์ด์ฉํด ๋จ๋ฐฉํฅ ์ฐ๊ฒฐ๋ฆฌ์คํธ๋ฅผ ์ญ์์ผ๋ก ์ํํ๋ฉด์ ํฌ์ธํฐ๋ฅผ ์ ๋ฐ์ดํธํ๋ ๋ฐฉ์์ผ๋ก ๊ตฌํ๋์ด ์์ต๋๋ค. ํ ๋ฒ์ ์ํ๋ก O(n) ์๊ฐ, O(1) ์ถ๊ฐ ๊ณต๊ฐ์ผ๋ก ์ญ์ ๋ฆฌ์คํธ๋ฅผ ๋ง๋ญ๋๋ค.
๐ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋ ๋ถ์
| ๋ณต์ก๋ | |
|---|---|
| Time | O(n) |
| Space | O(1) |
ํผ๋๋ฐฑ: ์์ ๊ณต๊ฐ์ผ๋ก ๋จ๋ฐฉํฅ ๋ฆฌ์คํธ๋ฅผ ์ญ์ ํ๋ ํ์ค ํจํด์ ์ฌ์ฉํฉ๋๋ค.
๊ฐ์ ์ ์: ํ์ฌ ๊ตฌํ์ด ์ ์ ํด ๋ณด์ ๋๋ค.
๐ก ํ์ด์ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋๋ฅผ ์ฃผ์์ผ๋ก ๋จ๊ฒจ๋ณด์ธ์!
There was a problem hiding this comment.
๐ท๏ธ ์๊ณ ๋ฆฌ์ฆ ํจํด ๋ถ์
set-matrix-zeroes/alphaorderly.py
"""
Time Complexity: O(m * n)
Space Complexity: O(1)
Approach:
- Use the first row and first column as markers to track which rows and columns should be zeroed.
- First, check if the original first row or first column should be zeroed by scanning them separately.
- Then, scan the rest of the matrix. If an element is zero, set its corresponding first row and first column positions to zero.
- Next, iterate through the matrix (excluding the first row and column) and set elements to zero if their corresponding first row or first column are zero.
- Finally, zero the first row and/or first column if initially flagged.
"""
class Solution:
def setZeroes(self, matrix: List[List[int]]) -> None:
ROW = len(matrix)
COL = len(matrix[0])
row_zero_check = any(matrix[0][c] == 0 for c in range(COL))
col_zero_check = any(matrix[r][0] == 0 for r in range(ROW))
for r in range(ROW):
for c in range(COL):
if matrix[r][c] == 0:
matrix[r][0] = 0
matrix[0][c] = 0
for r in range(1, ROW):
for c in range(1, COL):
if matrix[r][0] == 0 or matrix[0][c] == 0:
matrix[r][c] = 0
if row_zero_check:
for c in range(COL):
matrix[0][c] = 0
if col_zero_check:
for r in range(ROW):
matrix[r][0] = 0- ํจํด: Two Pointers, Greedy, Dynamic Programming, Hash Map / Hash Set, Bit Manipulation, Divide and Conquer, Union Find, Trie, BFS, DFS, Backtracking, Heap / Priority Queue, Monotonic Stack, Binary Search, Sliding Window
- ์ค๋ช : ์ด ์ฝ๋๋ ๊ณต๊ฐ ์ ์ฝ์ ์ํด ํ/์ด์ ํ์๊ธฐ๋ก ์ฌํ์ฉํ๋ ๋ฐฉ์์ผ๋ก 0์ ์์น๋ฅผ ์ ํํ๋ค. ํ๊ณผ ์ด ํ์๋ฅผ ํตํด ์ ์๋ฆฌ์์ ์ค์บํ๋ฉฐ ์กฐ๊ฑด์ ๋ง๋ ์์๋ฅผ 0์ผ๋ก ์ค์ ํ๋ ๊ธฐ๋ฒ์ ๋ํ์ ์ธ Sliding Window๊ฐ ์๋, ๊ณต๊ฐ ํจ์จ์ ๋ง์ปค ํ์ฉ ํจํด์ด๋ค.
๐ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋ ๋ถ์
| ๋ณต์ก๋ | |
|---|---|
| Time | O(m * n) |
| Space | O(1) |
ํผ๋๋ฐฑ: ๋ ๊ฐ์ ํ๋๊ทธ์ ํ/์ด ๋ง์ปค๋ฅผ ์ด์ฉํด ์์ ๊ณต๊ฐ์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
๊ฐ์ ์ ์: ํ์ฌ ๊ตฌํ์ด ์ ์ ํด ๋ณด์ ๋๋ค.
๐ก ํ์ด์ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋๋ฅผ ์ฃผ์์ผ๋ก ๋จ๊ฒจ๋ณด์ธ์!
There was a problem hiding this comment.
๐ท๏ธ ์๊ณ ๋ฆฌ์ฆ ํจํด ๋ถ์
unique-paths/alphaorderly.py
"""
Time Complexity: O(m * n)
Space Complexity: O(m * n)
Dynamic Programming (2D DP approach):
- Use a 2D array where maze[i][j] represents the number of unique paths to cell (i, j).
- Initialize the first row and first column with 1 (since there's only one way to reach each cell: only right moves for the first row or only down moves for the first column).
- For all other cells, maze[i][j] = maze[i-1][j] + maze[i][j-1] (sum of paths from the cell above and the cell to the left).
- Return maze[m-1][n-1] as the answer, which is the total number of unique paths.
"""
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
maze = [[1] * n for _ in range(m)]
for i in range(1, m):
for j in range(1, n):
maze[i][j] = maze[i - 1][j] + maze[i][j - 1]
return maze[m - 1][n - 1]
"""
Time Complexity: O(m * n)
Space Complexity: O(n)
Dynamic Programming (1D DP optimization):
- Use a 1D array dp of size n.
- dp[c] keeps track of the number of unique paths to column c in the current row.
- Initialize dp with 1s (the first row has only one way to reach each column).
- For every row from the second onward, update dp[c] = dp[c] + dp[c - 1] (add ways from the left neighbor to ways accumulated so far).
- Return dp[-1] as the answer, representing the number of unique paths to the bottom-right cell.
"""
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
dp = [1] * n
for _ in range(m - 1):
for c in range(1, n):
dp[c] += dp[c - 1]
return dp[-1]
"""
Time Complexity: O(m + n)
Space Complexity: O(1)
Combinatorial approach:
- The problem reduces to choosing (m-1) moves down from (m+n-2) total movements (or equivalently (n-1) moves right).
- The number of unique paths is given by the formula (m+n-2)! / [(m-1)! * (n-1)!], representing all possible orderings of down and right moves.
- Use the combinatorial (factorial) formula to compute the result efficiently.
"""
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
return comb(m + n - 2, n - 1)
"""
Time Complexity: O(m * n)
Space Complexity: O(m * n)
### Top down dynamic programming (with memoization) ###
Approach:
- Use recursion with memoization (via functools.cache) to store the number of unique paths to (row, col).
- The recursive function dp(row, col) returns the number of unique paths from the top-left to (row, col).
- Base case: If row == 1 or col == 1, there's only one unique path.
- Otherwise, dp(row, col) = dp(row-1, col) + dp(row, col-1).
- The answer is dp(m, n), the number of unique paths to the bottom-right cell.
"""
class Solution:
@cache
def uniquePaths(self, m: int, n: int) -> int:
return 1 if (m == 1 or n == 1) else self.uniquePaths(m - 1, n) + self.uniquePaths(m, n - 1)- ํจํด: Dynamic Programming, Monotonic Stack, Hash Map / Hash Set, Greedy, Divide and Conquer, Two Pointers, Sliding Window, Fast & Slow Pointers, BFS, DFS, Backtracking, Union Find, Trie, Bit Manipulation, Heap / Priority Queue
- ์ค๋ช : ์ฃผ๋ก 2D/1D DP๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ํจํด์ด ์ฌ์ฉ๋๋ฉฐ, ์ต๋จ ๊ฒฝ๋ก ์๋ฅผ ๊ตฌํ๋ ๋ํ์ ์ธ ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ(DP) ํจํด(๋ฉ๋ชจ์ด์ ์ด์ , ๋ฐํ ์ , ๊ณต๊ฐ ์ต์ ํ)๊ณผ ์ฌ๊ท + ๋ฉ๋ชจ์ด์ ์ด์ (ํ์ ๊ธฐ๋ฐ DP)์ด ํฌํจ๋ฉ๋๋ค. ๋ค๋ฅธ ํจํด์ ์ฌ์ฉ๋์ง ์์ต๋๋ค.
๐ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋ ๋ถ์
| ๋ณต์ก๋ | |
|---|---|
| Time | O(m * n) |
| Space | O(m * n) |
ํผ๋๋ฐฑ: ๋ค์ํ ์๋ฃจ์ ์ด ์ ์๋์ด ์์ด ์ ํ์ ํญ์ด ๋์ต๋๋ค. ๊ธฐ๋ณธ DP ์ ๊ทผ์ด ๊ฐ์ฅ ์ง๊ด์ ์ ๋๋ค.
๊ฐ์ ์ ์: ํ์ฌ ๊ตฌํ์ด ์ ์ ํด ๋ณด์ ๋๋ค.
๐ก ํ์ด์ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋๋ฅผ ์ฃผ์์ผ๋ก ๋จ๊ฒจ๋ณด์ธ์!
There was a problem hiding this comment.
๐ท๏ธ ์๊ณ ๋ฆฌ์ฆ ํจํด ๋ถ์
set-matrix-zeroes/alphaorderly.py
"""
Time Complexity: O(m * n)
Space Complexity: O(1)
Approach:
- Use the first row and first column as markers to track which rows and columns should be zeroed.
- First, check if the original first row or first column should be zeroed by scanning them separately.
- Then, scan the rest of the matrix. If an element is zero, set its corresponding first row and first column positions to zero.
- Next, iterate through the matrix (excluding the first row and column) and set elements to zero if their corresponding first row or first column are zero.
- Finally, zero the first row and/or first column if initially flagged.
"""
class Solution:
def setZeroes(self, matrix: List[List[int]]) -> None:
ROW = len(matrix)
COL = len(matrix[0])
row_check = any(matrix[0][c] == 0 for c in range(COL))
col_check = any(matrix[r][0] == 0 for r in range(ROW))
for r in range(ROW):
for c in range(COL):
if matrix[r][c] == 0:
matrix[r][0] = 0
matrix[0][c] = 0
for r in range(1, ROW):
for c in range(1, COL):
if matrix[r][0] == 0 or matrix[0][c] == 0:
matrix[r][c] = 0
if row_check:
for c in range(COL):
matrix[0][c] = 0
if col_check:
for r in range(ROW):
matrix[r][0] = 0- ํจํด: Two Pointers, Monotonic Stack, Hash Map / Hash Set, Greedy, Dynamic Programming, Binary Search, BFS, DFS, Backtracking, Divide and Conquer, Union Find, Trie, Bit Manipulation, Heap / Priority Queue
- ์ค๋ช : ์ฃผ์ด์ง ์ฝ๋๋ ์ถ๊ฐ ๋ฉ๋ชจ๋ฆฌ ์์ด ํ๊ณผ ์ด์ ์ ๋ณด๋ฅผ ํ/์ด์ ์ฒซ ํ๊ณผ ์ฒซ ์ด์ ๋ง์ปค๋ก ์ฌ์ฌ์ฉํ๋ ๋ฐฉ์์ผ๋ก 0์ผ๋ก ๋ง๋๋ ๋ฌธ์ ๋ค. ์ด๋ฅผ ํตํด ์ถ๊ฐ ๋ฐฐ์ด ์์ด ์ ๋ก ์์น๋ฅผ ํ์ํ๊ณ ์์ฐจ์ ์ผ๋ก ๊ฐ์ ๋ฐ๊พธ๋ ๋ฐฉ์์ ๊ณต๊ฐ ์ ์ฝ ํจํด์ ๋ํ์ ์ธ ์๋ก 'Two Pointers'์ ์ ๊ทผ๊ณผ ์ธ๋ฑ์ค ๋ง์ปค๋ฅผ ํ์ฉํ ์ ๋ก ๋ฐฐ์น๋ก ํด์ํ ์ ์๋ค.
๐ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋ ๋ถ์
| ๋ณต์ก๋ | |
|---|---|
| Time | O(m * n) |
| Space | O(1) |
ํผ๋๋ฐฑ: ๊ณต๊ฐ ์ ์ฝ์ ์ํด ์ฒซ ํ/์ด์ ๋ง์ปค๋ก ์ฌํ์ฉํ๊ณ ์ด๊ธฐ ์ํ๋ฅผ ํ์ธํด ์ ๋ก๋ง์ ๋ง์น ๋ค ๋ค์ ์ฒซ ํ/์ด์ ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ ๋๋ค.
๊ฐ์ ์ ์: ํ์ฌ ๊ตฌํ์ด ์ ์ ํด ๋ณด์ ๋๋ค.
๐ก ํ์ด์ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋๋ฅผ ์ฃผ์์ผ๋ก ๋จ๊ฒจ๋ณด์ธ์!
There was a problem hiding this comment.
๐ท๏ธ ์๊ณ ๋ฆฌ์ฆ ํจํด ๋ถ์
unique-paths/alphaorderly.py
"""
Time Complexity: O(m * n)
Space Complexity: O(m * n)
Dynamic Programming (2D DP approach):
- Use a 2D array where maze[i][j] represents the number of unique paths to cell (i, j).
- Initialize the first row and first column with 1 (since there's only one way to reach each cell: only right moves for the first row or only down moves for the first column).
- For all other cells, maze[i][j] = maze[i-1][j] + maze[i][j-1] (sum of paths from the cell above and the cell to the left).
- Return maze[m-1][n-1] as the answer, which is the total number of unique paths.
"""
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
maze = [[1] * n for _ in range(m)]
for i in range(1, m):
for j in range(1, n):
maze[i][j] = maze[i - 1][j] + maze[i][j - 1]
return maze[m - 1][n - 1]
"""
Time Complexity: O(m * n)
Space Complexity: O(n)
Dynamic Programming (1D DP optimization):
- Use a 1D array dp of size n.
- dp[c] keeps track of the number of unique paths to column c in the current row.
- Initialize dp with 1s (the first row has only one way to reach each column).
- For every row from the second onward, update dp[c] = dp[c] + dp[c - 1] (add ways from the left neighbor to ways accumulated so far).
- Return dp[-1] as the answer, representing the number of unique paths to the bottom-right cell.
"""
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
dp = [1] * n
for _ in range(m - 1):
for c in range(1, n):
dp[c] += dp[c - 1]
return dp[-1]
"""
Time Complexity: O(m + n)
Space Complexity: O(1)
Combinatorial approach:
- The problem reduces to choosing (m-1) moves down from (m+n-2) total movements (or equivalently (n-1) moves right).
- The number of unique paths is given by the formula (m+n-2)! / [(m-1)! * (n-1)!], representing all possible orderings of down and right moves.
- Use the combinatorial (factorial) formula to compute the result efficiently.
"""
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
return comb(m + n - 2, n - 1)
"""
Time Complexity: O(m * n)
Space Complexity: O(m * n)
### Top down dynamic programming (with memoization) ###
Approach:
- Use recursion with memoization (via functools.cache) to store the number of unique paths to (row, col).
- The recursive function dp(row, col) returns the number of unique paths from the top-left to (row, col).
- Base case: If row == 1 or col == 1, there's only one unique path.
- Otherwise, dp(row, col) = dp(row-1, col) + dp(row, col-1).
- The answer is dp(m, n), the number of unique paths to the bottom-right cell.
"""
class Solution:
@cache
def uniquePaths(self, m: int, n: int) -> int:
if m == 1 or n == 1:
return 1
return self.uniquePaths(m - 1, n) + self.uniquePaths(m, n - 1)- ํจํด: Dynamic Programming, Binary Search
- ์ค๋ช : ์ฃผ๋ก 2D/1D DP๋ก ๊ฒฉ์ ๊ฒฝ๋ก์ ํฉ์ ๊ตฌํ๊ฑฐ๋ ์ฌ๊ท+๋ฉ๋ชจํ๋ก ํด๋ฅผ ์ฐพ๋ ๋ฐฉ์์ด ํต์ฌ์ด๋ฏ๋ก Dynamic Programming์ด ์ฃผ ํจํด์ด๊ณ , ์ฃผ์ด์ง ์ฝ๋๋ ์ต๋จ ๊ฒฝ๋ก์ ์กฐํฉ ์๋ฅผ DP๋ก ์ ํํ ๊ณ์ฐํฉ๋๋ค. Binary Search ํจํด์ ๋ณธ ์ฝ๋์ ํด๋นํ์ง ์์ต๋๋ค.
๐ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋ ๋ถ์
โน๏ธ ์ด ํ์ผ์๋ 4๊ฐ์ง ํ์ด๊ฐ ํฌํจ๋์ด ์์ด ๊ฐ๊ฐ ๋ถ์ํฉ๋๋ค.
ํ์ด 1: Solution.uniquePaths โ Time: O(m * n) / Space: O(m * n)
| ๋ณต์ก๋ | |
|---|---|
| Time | O(m * n) |
| Space | O(m * n) |
ํผ๋๋ฐฑ: 2D DP ๋ฐฐ์ด์ ์ฌ์ฉํด ๋ชจ๋ ๊ฒฝ๋ก ์๋ฅผ ๋์ ๊ณ์ฐํฉ๋๋ค. ์ง๊ด์ ์ด์ง๋ง ๊ณต๊ฐ ์ฌ์ฉ์ด ํฝ๋๋ค.
๊ฐ์ ์ ์: ํ์ฌ ๊ตฌํ์ด ์ ์ ํด ๋ณด์ ๋๋ค.
ํ์ด 2: Solution.uniquePaths โ Time: O(m * n) / Space: O(n)
| ๋ณต์ก๋ | |
|---|---|
| Time | O(m * n) |
| Space | O(n) |
ํผ๋๋ฐฑ: ํ ์ํ ์ ํ์ฌ ์ด์ ๊ฒฝ๋ก ์๋ฅผ ์ผ์ชฝ ์ด์๊ณผ ํฉ์ณ ๊ฐฑ์ ํ๋ฏ๋ก ์ถ๊ฐ ๋ฐฐ์ด ์์ด๋ ๊ฒฐ๊ณผ๋ฅผ ๊ตฌํฉ๋๋ค.
๊ฐ์ ์ ์: ํ์ฌ ๊ตฌํ์ด ์ ์ ํด ๋ณด์ ๋๋ค.
ํ์ด 3: Solution.uniquePaths โ Time: O(1) / Space: O(1)
| ๋ณต์ก๋ | |
|---|---|
| Time | O(1) |
| Space | O(1) |
ํผ๋๋ฐฑ: ๊ฒฐํฉ ๊ณ์ฐ์ผ๋ก ํด๋ฅผ ์ง์ ๊ตฌํ๋ ๋ฐฉ๋ฒ์ผ๋ก ์ต์ ์ ์๊ฐ/๊ณต๊ฐ์ ์ ๊ณตํฉ๋๋ค(ํฉํ ๋ฆฌ์ผ ํ์ ์ ํฐ ์ ์ฃผ์).
๊ฐ์ ์ ์: ํ์ฌ ๊ตฌํ์ด ์ ์ ํด ๋ณด์ ๋๋ค.
ํ์ด 4: Solution.uniquePaths โ Time: O(m * n) / Space: O(m * n)
| ๋ณต์ก๋ | |
|---|---|
| Time | O(m * n) |
| Space | O(m * n) |
ํผ๋๋ฐฑ: ์ฌ๊ท + ์บ์๋ก ์ค๋ณต ๊ณ์ฐ์ ํผํ์ง๋ง ์คํ ๊น์ด ๋ฐ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ์ด ์ฆ๊ฐํฉ๋๋ค.
๊ฐ์ ์ ์: ํ์ฌ ๊ตฌํ์ด ์ ์ ํด ๋ณด์ ๋๋ค.
๐ก ํ์ด์ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋๋ฅผ ์ฃผ์์ผ๋ก ๋จ๊ฒจ๋ณด์ธ์!
|
@parkhojeong |
๋ต์ ์ ์ถ ๋ฌธ์
์์ฑ์ ์ฒดํฌ ๋ฆฌ์คํธ
In Review๋ก ์ค์ ํด์ฃผ์ธ์.๊ฒํ ์ ์ฒดํฌ ๋ฆฌ์คํธ
Important
๋ณธ์ธ ๋ต์ ์ ์ถ ๋ฟ๋ง ์๋๋ผ ๋ค๋ฅธ ๋ถ PR ํ๋ ์ด์์ ๋ฐ๋์ ๊ฒํ ๋ฅผ ํด์ฃผ์ ์ผ ํฉ๋๋ค!