Skip to content

Commit eef3a80

Browse files
committed
solve(w14): 213. House Robber II
1 parent 13f1335 commit eef3a80

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

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)

0 commit comments

Comments
 (0)