My code
1
2
3
4
5
6
7
8
9
10
11
| class Solution:
def rob(self, nums: List[int]) -> int:
if len(nums) < 3:
return max(nums)
memo = [0 * _ for _ in range(len(nums))]
memo[0],memo[1] = nums[0],nums[1]
for i in range(2,len(nums)):
memo[i] = max(nums[i],nums[i] + max(memo[0:i - 1]))
return max(memo[-1],memo[-2])
|
1
2
| Runtime : 31ms (beats 96.23%)
Memory : 16.20MB (beats 70.68%)
|
풀이
nums
의 길이가 3보다 작을 시에는 nums가 1개 혹은 2개일 때 이므로 배열의 최대값이 정답이 된다.
memorizatoin
을 사용하여 메모리를 줄이기 위해 미리 0으로 이루어진 nums길이의 배열 memo
를 선언. 이 배열에는 해당 인덱스까지 더할 수 있는 가장 큰 합이 들어간다.
- 3번째 원소부터 비교하기 위해
nums[0]
,nums[1]
을 미리 memo
에 넣어둔다.
i = 3
부터, memo[i-2]
까지의 max값에 nums[i]
를 더한 값과, nums[i]
를 비교하여 max값을 넣는다.
- 이를 반복하면
memo
의 마지막 칸에는 nums
의 마지막에서 두번째 숫자 nums[i-1]
을 고려하지 않은 결과가 들어가기 때문에, memo[-1]
과 memo[-2]
중 큰 값을 반환한다
문제를 풀 때 DP라는 것을 아는데는 얼마 걸리지 않았지만 DP 안에서 어떤 로직을 짜야 할지 생각하는 부분이 힘들었다.
먼저 맨 처음은 위의 길이가 2 이하일때 max(nums)
를 반환하는 식을 넣지 않았었는데, for문을 돌며 out of index 오류가 나서 조건을 추가해주었다. 또한 처음에는 if len(nums) < 2:
였는데, 이는 길이가 1일때만 동작하지만 밑에 for문에서 range(2,2)
가 되어 for문이 돌아가지 않고 return 구문에서 max로 답이 나오는 조금 이상한 코드가 되어 고쳐주었다.
1
2
3
4
5
6
7
8
9
10
11
12
| class Solution:
def rob(self, nums: List[int]) -> int:
if len(nums) < 3: return max(nums)
dp = [0] * len(nums)
dp[0] = nums[0]
dp[1] = max(nums[0], nums[1])
for i in range(len(nums) -2):
dp[i+2] = max(dp[i]+nums[i+2], dp[i+1])
return dp[-1]
|
같이 코드리뷰를 진행한 친구의 코드인데, 같은 memorization 방식이지만 배열에 담기는 값이 그 인덱스 위치에서 나올 수 있는 합의 최대값으로 더 명확하다.