House Robber
https://leetcode.com/problems/house-robber/
Example of dp.
Intuition, when robbed the first house, or we skipped it, the problem is reduced…
Approach 1: Memoization
dp: dict[int, int] = {}
n = len(nums)
def rob_from(i):
if i >= n:
return 0
if i in dp:
return dp[i]
ans = max(
rob_from(i + 1),
rob_from(i + 2) + nums[i]
)
dp[i] = ans
return ans
return rob_from(0)Approach 2: DP
A tabular approach isn’t necessarily “bottom-up”!
n = len(nums)
max_amount = [None] * (n + 1)
max_amount[n] = 0 # no house left, cannot obtain more money
max_amount[n - 1] = nums[n - 1] # one house left, rob it
for i in range(n - 2, -1, -1):
# rob from i-th house, i included
max_amount[i] = max(
max_amount[i + 1], # don't rob this, rob next
max_amount[i + 2] + nums[i] # rob this and second next
)
return max_amount[0]Approach 3: Optimized DP
Observe that max_amount[i] only depends on the previous two values at i + 1 and i + 2. Space complexity also optimized.
n = len(nums)
rob_next_next = 0 # there's no next next, no house left!
rob_next = nums[n - 1] # there's one house left, rob it
for i in range(n - 2, -1, -1):
current = max(rob_next, rob_next_next + nums[i])
rob_next_next = rob_next
rob_next = current
return rob_nextAn alternative code
t1 = 0 # max amt robbed up to the current house
t2 = 0 # max amt robbed up to before the current house
for current in nums:
t1, t2 = max(current + t2, t1), t1
return t1Think of t1 and t2 as two thieves
t1leaves a note of max amount that can be robbed up to this houset2enters the house, communicate this info witht1through walkie-talkie. At this time,t1is at the next house- The two thieves decide should they rob or not