Example 1
ready- Input
nums = [ 1, 2, 3, 1 ]- Expected
4- Why
- houses 0 and 2 contribute 1 + 3
Every house offers cash, but each choice can lock the next door.
The array nums lists the amount available in each house along one street. You can't
rob two adjacent houses, meaning houses whose indices differ by exactly 1. Return
the largest total you can collect without choosing an adjacent pair.
You may skip any house. A house may contain 0, and each amount can be used at most
once.
1 <= nums.length <= 1000 <= nums[i] <= 400Hints
At house i, either skip it and keep the best total through i - 1, or take it
and add its cash to the best total through i - 2.
Let best[i] mean the best total from the first i houses. Write the two
choices using that state before you write any loop.
The next decision reads only the best totals from one and two houses back. Those two values can roll forward with you.
Can you also reconstruct which house indices produce the maximum total? What extra information would you keep?
Visible cases
nums = [
1,
2,
3,
1
]4nums = [
2,
7,
9,
3,
1
]12nums = [
2,
1,
1,
2
]4Interview signal
At index i, make the choice literally:
i + 1, ori + 2.def rob(nums: list[int]) -> int:
def best_from(i: int) -> int:
if i >= len(nums):
return 0
skip = best_from(i + 1)
take = nums[i] + best_from(i + 2)
return max(skip, take)
return best_from(0)Both branches ask for the same suffixes again and again, which creates an exponential decision tree.
Time O(2ⁿ). Space O(n) for the recursion stack.
Dynamic programming (DP) stores answers to recurring subproblems. Count houses from the left so the state doesn't need awkward negative indices:
dp[i] is the largest total available from the first i houses.dp[i] = max(dp[i - 1], dp[i - 2] + nums[i - 1]). The first term
skips the current house; the second takes it.dp[0] = 0 and dp[1] = nums[0].Only the previous two states feed the transition. Keep those two totals instead of the whole table.
def rob(nums: list[int]) -> int:
two_houses_back = 0
one_house_back = 0
for cash in nums:
current = max(one_house_back, two_houses_back + cash)
two_houses_back = one_house_back
one_house_back = current
return one_house_backBefore each update, one_house_back is the best total if you skip the current house,
while two_houses_back + cash is the best total if you take it. Choosing the larger
preserves the optimal answer for the processed prefix.
Time O(n). Space O(1).
Ready to run.
3 cases are queued.
Visible testcase
Case 1
Expected
4