Skip to content

Commit a2c88d8

Browse files
authored
Merge pull request #1635 from seungriyou/main
[seungriyou] Week 14 Solutions
2 parents 907b4b6 + 3ec3b9e commit a2c88d8

File tree

5 files changed

+443
-0
lines changed

5 files changed

+443
-0
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# https://leetcode.com/problems/binary-tree-level-order-traversal/
2+
3+
from typing import Optional, List
4+
5+
# Definition for a binary tree node.
6+
class TreeNode:
7+
def __init__(self, val=0, left=None, right=None):
8+
self.val = val
9+
self.left = left
10+
self.right = right
11+
12+
class Solution:
13+
def levelOrder_bfs(self, root: Optional[TreeNode]) -> List[List[int]]:
14+
"""
15+
[Complexity]
16+
- TC: O(n)
17+
- SC: O(width) (์ตœ์•…์˜ ๊ฒฝ์šฐ O(n)) (๊ฒฐ๊ณผ res ์ œ์™ธ)
18+
19+
[Approach]
20+
๋ ˆ๋ฒจ ๋ณ„๋กœ BFS๋กœ ์ ‘๊ทผ
21+
"""
22+
if not root:
23+
return []
24+
25+
res, level = [], [root]
26+
27+
while level:
28+
# res์— ํ˜„์žฌ level ๋‚ด node value ์ถ”๊ฐ€
29+
res.append([node.val for node in level])
30+
31+
# next level์˜ node๋กœ level ์—…๋ฐ์ดํŠธ
32+
level = [child for node in level for child in (node.left, node.right) if child]
33+
# next_level = []
34+
# for node in level:
35+
# if node.left:
36+
# next_level.append(node.left)
37+
# if node.right:
38+
# next_level.append(node.right)
39+
# level = next_level
40+
41+
return res
42+
43+
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
44+
"""
45+
[Complexity]
46+
- TC: O(n)
47+
- SC: O(height) (call stack) (๊ฒฐ๊ณผ res ์ œ์™ธ)
48+
49+
[Approach]
50+
๋ ˆ๋ฒจ ๋ณ„๋กœ DFS๋กœ ์ ‘๊ทผ
51+
"""
52+
if not root:
53+
return []
54+
55+
res = []
56+
57+
def dfs(node, level):
58+
# base condition (๊ฐ level์˜ ์ฒซ ์‹œ์ž‘)
59+
if len(res) == level:
60+
res.append([])
61+
62+
# ํ˜„์žฌ level์— node.val ์ถ”๊ฐ€
63+
res[level].append(node.val)
64+
65+
# node์˜ child์— ๋Œ€ํ•ด ๋‹ค์Œ level๋กœ ์ง„ํ–‰
66+
if node.left:
67+
dfs(node.left, level + 1)
68+
if node.right:
69+
dfs(node.right, level + 1)
70+
71+
dfs(root, 0)
72+
73+
return res

โ€Žcounting-bits/seungriyou.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# https://leetcode.com/problems/counting-bits/
2+
3+
from typing import List
4+
5+
class Solution:
6+
def countBits1(self, n: int) -> List[int]:
7+
"""
8+
[Complexity]
9+
- TC: O(n)
10+
- SC: O(n)
11+
12+
[Approach]
13+
๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ทœ์น™์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.
14+
15+
0 ~ 1 bin(0) = 0
16+
bin(1) = 1
17+
18+
2 ~ 3 bin(2) = 10 = 10 + bin(0)
19+
bin(3) = 11 = 10 + bin(1)
20+
=> offset = 10(2) = 2 (-> 1์ด 1๊ฐœ)
21+
22+
4 ~ 7 bin(4) = 100 = 100 + bin(0)
23+
bin(5) = 101 = 100 + bin(1)
24+
bin(6) = 110 = 100 + bin(2)
25+
bin(7) = 111 = 100 + bin(3)
26+
=> offset = 100(2) = 4 (-> 1์ด 1๊ฐœ)
27+
28+
8 ~ 15 bin(8) = 1000 = 1000 + bin(0)
29+
...
30+
bin(15) = 1111 = 1000 + bin(7)
31+
=> offset = 1000(2) = 8 (-> 1์ด 1๊ฐœ)
32+
"""
33+
34+
dp = [0] * (n + 1)
35+
offset = 1
36+
37+
for i in range(1, n + 1):
38+
# i๊ฐ€ 2์˜ ์ œ๊ณฑ์ด๋ฉด, offset 2๋ฐฐ
39+
if offset * 2 == i:
40+
offset *= 2
41+
42+
# ์ด์ „์— ๊ตฌํ•œ ๊ฐ’ ์‚ฌ์šฉ
43+
dp[i] = dp[i - offset] + 1
44+
45+
return dp
46+
47+
def countBits(self, n: int) -> List[int]:
48+
"""
49+
[Complexity]
50+
- TC: O(n)
51+
- SC: O(n)
52+
"""
53+
54+
dp = [0] * (n + 1)
55+
for i in range(1, n + 1):
56+
# dp[i] = dp[i // 2] + (i % 2)
57+
dp[i] = dp[i >> 1] + (i & 1)
58+
59+
return dp

โ€Žhouse-robber-ii/seungriyou.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# https://leetcode.com/problems/house-robber-ii/
2+
3+
from typing import List
4+
5+
class Solution:
6+
def rob_on(self, nums: List[int]) -> int:
7+
"""
8+
[Complexity]
9+
- TC: O(n)
10+
- SC: O(n)
11+
12+
[Approach]
13+
์ง‘๋“ค์ด ์›์„ ์ด๋ฃจ๊ณ  ์žˆ๊ณ  ์ธ์ ‘ํ•œ ๋‘ ์ง‘์„ ๋ชจ๋‘ ๋ฐฉ๋ฌธํ•˜๋ฉด ์•ˆ ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‘ ๊ฐ€์ง€ ์ƒํ™ฉ์œผ๋กœ max money๋ฅผ ๊ตฌํ•œ๋‹ค.
14+
(์›ํ˜•์ด๋ผ๋Š” ์ ์„ ๊ณ ๋ คํ•˜์ง€ ์•Š์œผ๋ฉด ์ฒซ ๋ฒˆ์งธ ์ง‘๊ณผ ๋งˆ์ง€๋ง‰ ์ง‘์„ ๋ชจ๋‘ ๋ฐฉ๋ฌธํ•˜๊ฒŒ ๋  ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ)
15+
(1) ์ฒซ ๋ฒˆ์งธ ์ง‘์„ ์ œ์™ธ
16+
(2) ๋งˆ์ง€๋ง‰ ์ง‘์„ ์ œ์™ธ
17+
๊ทธ๋ฆฌ๊ณ  ๋‘ ๊ฐ’ ์ค‘ ํฐ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
18+
19+
dp[i] = nums[i]๊นŒ์ง€ ํ™•์ธํ–ˆ์„ ๋•Œ์˜ max money
20+
dp[i] = max(dp[i - 1], dp[i - 2] + num)
21+
"""
22+
n = len(nums)
23+
24+
# early stop
25+
if n <= 3:
26+
return max(nums)
27+
28+
dp1 = [0] * (n - 1) # ๋งˆ์ง€๋ง‰ ์ง‘ ์ œ์™ธ: nums[0] ~ nums[n - 2]
29+
dp2 = [0] * (n - 1) # ์ฒซ ๋ฒˆ์งธ ์ง‘ ์ œ์™ธ: nums[1] ~ nums[n - 1]
30+
31+
# initialize
32+
dp1[0], dp2[0] = nums[0], nums[1]
33+
dp1[1], dp2[1] = max(dp1[0], nums[1]), max(dp2[0], nums[2])
34+
35+
for i in range(2, n - 1):
36+
dp1[i] = max(dp1[i - 1], dp1[i - 2] + nums[i])
37+
dp2[i] = max(dp2[i - 1], dp2[i - 2] + nums[i + 1])
38+
39+
return max(dp1[-1], dp2[-1])
40+
41+
def rob(self, nums: List[int]) -> int:
42+
"""
43+
[Complexity]
44+
- TC: O(n)
45+
- SC: O(1)
46+
47+
[Approach]
48+
์ด์ „ O(n) space DP ํ’€์ด์—์„œ dp[i] ๊ฐ’์„ ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด dp[i - 1] & dp[i - 2] ๊ฐ’๋งŒ ์ฐธ๊ณ ํ•˜๋ฏ€๋กœ,
49+
O(1) space๋กœ optimize ํ•  ์ˆ˜ ์žˆ๋‹ค.
50+
"""
51+
n = len(nums)
52+
53+
# early stop
54+
if n <= 3:
55+
return max(nums)
56+
57+
# p2 = dp[i - 2], p1 = dp[i - 1]
58+
f_p2 = f_p1 = 0 # ๋งˆ์ง€๋ง‰ ์ง‘ ์ œ์™ธ: nums[0] ~ nums[n - 2]
59+
l_p2 = l_p1 = 0 # ์ฒซ ๋ฒˆ์งธ ์ง‘ ์ œ์™ธ: nums[1] ~ nums[n - 1]
60+
61+
for i in range(n - 1):
62+
f_p2, f_p1 = f_p1, max(f_p1, f_p2 + nums[i])
63+
l_p2, l_p1 = l_p1, max(l_p1, l_p2 + nums[i + 1])
64+
65+
return max(f_p1, l_p1)

โ€Žmeeting-rooms-ii/seungriyou.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# https://leetcode.com/problems/meeting-rooms-ii/
2+
3+
from typing import List
4+
5+
class Solution:
6+
def minMeetingRooms_heap(self, intervals: List[List[int]]) -> int:
7+
"""
8+
[Complexity]
9+
- TC: O(nlogn) (sort & heappop/push)
10+
- SC: O(n) (min heap)
11+
12+
[Approach]
13+
๊ธฐ๋ณธ์ ์œผ๋กœ ํšŒ์˜ ์‹œ์ž‘ ์‹œ๊ฐ์ด ๋น ๋ฅธ ์ˆœ์„œ๋กœ ์‚ดํŽด๋ณด์•„์•ผ ํ•œ๋‹ค.
14+
์‹œ์ž‘ ์‹œ๊ฐ ์ด์ „์— ์–ด๋–ค ํšŒ์˜์‹ค์ด ๋นˆ๋‹ค๋ฉด ํ•ด๋‹น ํšŒ์˜์‹ค์„ ์ด์–ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ 
15+
์‹œ์ž‘ ์‹œ๊ฐ ์ดํ›„๊นŒ์ง€ ๊ธฐ์กด ํšŒ์˜๊ฐ€ ๋งˆ์น˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ํ•ด๋‹น ํšŒ์˜์‹ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.
16+
์ด๋ฅผ ๋งค๋ฒˆ ๋น ๋ฅด๊ฒŒ ํŒ๋‹จํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ทธ๋ฆฌ๋””ํ•˜๊ฒŒ
17+
"์ด์ „๊นŒ์ง€ ํšŒ์˜์‹ค์„ ์‚ฌ์šฉํ•˜๋˜ ํšŒ์˜ ์ค‘ ๊ฐ€์žฅ ๋นจ๋ฆฌ ๋งˆ์น˜๋Š” ํšŒ์˜์˜ ์ข…๋ฃŒ ์‹œ๊ฐ"๊ณผ "ํ˜„์žฌ ๋ณด๊ณ  ์žˆ๋Š” ํšŒ์˜ ์‹œ์ž‘ ์‹œ๊ฐ"
18+
์„ ๋น„๊ตํ•˜๋ฉด ๋œ๋‹ค.
19+
ํ•ญ์ƒ ํšŒ์˜์˜ ์ข…๋ฃŒ ์‹œ๊ฐ ์ค‘ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’์„ ๊ณ ๋ฅด๋ฉด ๋˜๋ฏ€๋กœ, min heap์„ ์ด์šฉํ•˜์—ฌ ์ตœ์†Ÿ๊ฐ’์„ O(1)์— ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค.
20+
"""
21+
import heapq
22+
23+
# ํšŒ์˜ ์‹œ์ž‘ ์‹œ๊ฐ ์ˆœ์œผ๋กœ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ
24+
intervals.sort()
25+
26+
# min heap
27+
rooms = []
28+
29+
for s, e in intervals:
30+
# "์ด์ „๊นŒ์ง€ ํšŒ์˜์‹ค์„ ์‚ฌ์šฉํ•˜๋˜ ํšŒ์˜ ์ค‘ ๊ฐ€์žฅ ๋นจ๋ฆฌ ๋งˆ์น˜๋Š” ํšŒ์˜์˜ ์ข…๋ฃŒ ์‹œ๊ฐ"๊ณผ "ํ˜„์žฌ ๋ณด๊ณ  ์žˆ๋Š” ํšŒ์˜ ์‹œ์ž‘ ์‹œ๊ฐ"์ด ๊ฒน์น˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ,
31+
# rooms์— ์กด์žฌํ•˜๋Š” ํšŒ์˜์‹ค ์ค‘ e๊ฐ€ ๊ฐ€์žฅ ์ด๋ฅธ ํšŒ์˜์‹ค pop
32+
if rooms and rooms[0] <= s:
33+
heapq.heappop(rooms)
34+
35+
# ํ˜„์žฌ ํšŒ์˜ push
36+
heapq.heappush(rooms, e)
37+
38+
return len(rooms)
39+
40+
def minMeetingRooms(self, intervals: List[List[int]]) -> int:
41+
"""
42+
[Complexity]
43+
- TC: O(nlogn)
44+
- SC: O(n)
45+
46+
[Approach]
47+
start์™€ end๋ฅผ ๋‚˜๋ˆ„์–ด ์ •๋ ฌํ•œ๋‹ค๋ฉด, ๊ฐ๊ฐ์˜ ์›์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” two-pointer๋ฅผ ์ด์šฉํ•ด
48+
ํšŒ์˜์‹ค์„ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์™€ ์ƒˆ๋กœ์šด ํšŒ์˜์‹ค์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋ฅผ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋‹ค.
49+
starts๋ฅผ ์ˆœํšŒํ•˜๋ฉด์„œ e๋ผ๋Š” pointer๋กœ ends์˜ ์ฒซ๋ฒˆ์งธ ์›์†Œ๋ถ€ํ„ฐ ๋น„๊ตํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ผ€์ด์Šค๋ฅผ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค.
50+
- non-overlap(ends[e] <= s): ํšŒ์˜์‹ค ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ (e++๋ฅผ ํ†ตํ•ด ๋‹ค์Œ ํšŒ์˜ ์‚ดํŽด๋ณด๊ธฐ)
51+
- overlap(ends[e] > s): ์ƒˆ๋กœ์šด ํšŒ์˜์‹ค ํ•„์š”
52+
"""
53+
starts = sorted(s for s, _ in intervals)
54+
ends = sorted(e for _, e in intervals)
55+
56+
res = e = 0
57+
58+
for s in starts:
59+
# non overlap -> ํšŒ์˜์‹ค ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ (๋‹ค์Œ ํšŒ์˜ ์‚ดํŽด๋ณด๊ธฐ)
60+
if ends[e] <= s:
61+
e += 1
62+
# overlap -> ์ƒˆ๋กœ์šด ํšŒ์˜์‹ค ํ•„์š”
63+
else:
64+
res += 1
65+
66+
return res

0 commit comments

Comments
ย (0)