Open seungriyou opened 3 months ago
https://leetcode.com/problems/house-robber/
인접한 집을 털면 안 되기 때문에 nums[i] 까지 확인했을 때 가능한 가장 큰 금액은
nums[i]
nums[i - 1]
nums[i - 2]
중에서 더 큰 값이다.
따라서 이전에 구했던 값을 사용해야 하므로 다음과 같이 DP 테이블을 작성할 수 있다.
corner case를 고려하기 위해 dp[0]에는 0을 추가해줬다. dp[i]: nums[i - 1]까지 확인했을 때 가능한 가장 큰 금액
corner case를 고려하기 위해 dp[0]에는 0을 추가해줬다.
dp[0]
dp[i]: nums[i - 1]까지 확인했을 때 가능한 가장 큰 금액
DP 로직은 다음과 같이 작성할 수 있다.
for i in range(2, n + 1): # (1) 이전 집을 털 때와 (2) 그 이전 집을 털고 현재 집을 털 때 중 더 큰 값 기록 dp[i] = max(dp[i - 1], dp[i - 2] + nums[i - 1])
1D DP에서 dp[i]를 구할 때 dp[i - 1]과 dp[i - 2]만 확인하므로, 이를 O(n) space 리스트로 관리할 필요 없이 O(1) space 변수로 관리할 수 있다.
dp[i]
dp[i - 1]
dp[i - 2]
O(n)
O(1)
def rob(self, nums: List[int]) -> int: """O(1) space DP""" a, b = 0, 0 for num in nums: a, b = b, max(a + num, b) return b
Approach
Idea 1: 1D DP
인접한 집을 털면 안 되기 때문에
nums[i]
까지 확인했을 때 가능한 가장 큰 금액은nums[i]
를 택하지 않는 경우:nums[i - 1]
까지 확인했을 때의 가능한 가장 큰 금액nums[i]
를 택하는 경우:nums[i - 2]
까지 확인했을 때의 가능한 가장 큰 금액 +nums[i]
중에서 더 큰 값이다.
따라서 이전에 구했던 값을 사용해야 하므로 다음과 같이 DP 테이블을 작성할 수 있다.
DP 로직은 다음과 같이 작성할 수 있다.
Idea 2: O(1) Space DP
1D DP에서
dp[i]
를 구할 때dp[i - 1]
과dp[i - 2]
만 확인하므로, 이를O(n)
space 리스트로 관리할 필요 없이O(1)
space 변수로 관리할 수 있다.Complexity
O(n)
O(n)
/ (space optimized)O(1)