House Robber

Interview Problems Intermediate 2 min read Published
Medium Dynamic Programming Often asked at: Amazon, Google, Microsoft, Cisco, Airbnb, Apple
In this lesson

The classic “take it or skip it” DP. Once you get this one, dozens of problems open up.

The problem#

nums[i] is the money in house i along a street. You can’t rob two adjacent houses. Return the maximum you can take.

Examples#

numsanswerhouses robbed
[1, 2, 3, 1]41 + 3
[2, 7, 9, 3, 1]122 + 9 + 1
[2, 1, 1, 2]42 + 2

Hints#

Hint 1

Greedy (take every other house) fails on [2, 1, 1, 2]. You need to compare options.

Hint 2

At house i: skip it → best so far stays best(i − 1). Rob it → best(i − 2) + nums[i].

Hint 3

best(i) = max(best(i − 1), best(i − 2) + nums[i]). Only the last two values are needed.

The easy idea: a choice at every door#

Walk down the street. At each door, you ask one question:

  • “If I skip this house, I keep my best total from the previous house.”
  • “If I rob it, I add its money to my best total from two houses back (the neighbour must be skipped).”

Pick whichever is bigger, then move on.

housemoneyskip itrob itbest
02022
17277
2972 + 9 = 1111
33117 + 3 = 1011
411111 + 1 = 1212

Solution#

def rob(nums):
    two_back, one_back = 0, 0
    for money in nums:
        two_back, one_back = one_back, max(one_back, two_back + money)
    return one_back

print(rob([1, 2, 3, 1]))     # 4
print(rob([2, 7, 9, 3, 1]))  # 12
print(rob([2, 1, 1, 2]))     # 4
print(rob([]))               # 0

Complexity#

  • Time O(n), space O(1).

Follow-up: houses in a circle (House Robber II)#

The first and last houses are now neighbours. So either skip the first house or skip the last one, and take the better result:

def rob_line(nums):
    a, b = 0, 0
    for x in nums:
        a, b = b, max(b, a + x)
    return b

def rob_circle(nums):
    if len(nums) == 1:
        return nums[0]
    return max(rob_line(nums[1:]), rob_line(nums[:-1]))

print(rob_circle([2, 3, 2]))     # 3
print(rob_circle([1, 2, 3, 1]))  # 4

Similar problems#

House Robber II, House Robber III (houses in a tree), Delete and Earn, Maximum Sum of Non-Adjacent Elements.

Learn the pattern: Dynamic Programming.

Quick quiz

3 questions. Check what stuck and earn 2 XP for each right answer.

1Recurrence?
2Answer for [2,7,9,3,1]?
3Space?

Progress is saved in this browser. Create a free account to keep it on every device.