How to Explain House Robber in a Coding Interview (Step-by-Step)
House Robber is the second classic DP problem after Climbing Stairs — same two-variable rolling pattern, but with a decision at every step: rob this house or skip it. The key is framing it as a max subproblem and arriving at the clean O(n) O(1) solution.
In this post, you’ll learn exactly how to walk an interviewer through House Robber: the constraint, the recurrence relation, both DP approaches, and the two-variable space optimisation.
Problem Statement
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. The only constraint is that adjacent houses have security systems connected — if two adjacent houses are robbed on the same night, it will alert the police.
Given an integer array nums representing the amount of money at each house, return the maximum amount of money you can rob without alerting the police.
Examples
Output: 4
Explanation: Rob house 1 (1) + house 3 (3) = 4
Output: 22
Explanation: Rob houses 2, 4, 8 → 7+3+4+8 = 22… actually best is 7+1+8=16… rob 2,4,8 → 7+4+8=19… rob indices 1,4,7 → 7+4+8 = 19. Best: rob 1,3,5,7 → 7+1+4+8=20. Actually: 2+3+4+8=17 vs 7+1+4+8=20 ✓
Output: 4
Explanation: Rob house 1 (2) + house 4 (2) = 4
Constraints
1 <= nums.length <= 1000 <= nums[i] <= 400
What Is the Problem?
“I need to find the maximum sum of elements in an array such that no two chosen elements are adjacent. I can pick or skip each house — as long as I never pick two houses next to each other.”
Stripping away the story and framing it as a max non-adjacent sum problem immediately points toward DP.
Step 1: Walk Through All Three Approaches
Try every subset of non-adjacent houses — 2ⁿ subsets
Time: O(2ⁿ)
Space: O(n) stack
Exponential — recomputes same subproblems
Build dp[i] = max money robbing up to house i
Time: O(n)
Space: O(n)
Good — linear time, but uses O(n) array
Only keep track of previous two dp values
Time: O(n)
Space: O(1)
Optimal — same as Climbing Stairs trick
The Key Insight
At each house i, you have exactly two choices: rob it or skip it.
If you rob house i: you can’t rob house i−1, so you take nums[i] + best up to i−2.
If you skip house i: the best you can do is whatever you already had — best up to i−1.
The answer at each step is the maximum of those two choices. And since we only ever look back two steps, we only need two variables — not an array.
The Recurrence Relation
Spend time on this formula in the interview — it’s the entire problem:
“dp[i−2] + nums[i]is what we get if we rob house i — we had to skip house i−1 so our previous best is two steps back.dp[i−1]is what we get if we skip house i — we just carry forward the best from one step back. We take the max of both.”
Step 3: Talk Through the Code
Approach 1 — DP Array (mention first, good to explain)
class Solution:
def rob(self, nums: List[int]) -> int:
if len(nums) == 1:
return nums[0] # Only one house — rob it
dp = [0] * len(nums)
dp[0] = nums[0] # Base: rob first house
dp[1] = max(nums[0], nums[1])# Base: best of first two
for i in range(2, len(nums)):
# Rob house i: nums[i] + best two steps back
# Skip house i: carry forward best from one step back
dp[i] = max(nums[i] + dp[i-2], dp[i-1])
return dp[-1] # Max money robbing all n houses
Approach 2 — Two Variables O(1) Space (optimal, lead with this)
class Solution:
def rob(self, nums: List[int]) -> int:
prev2 = 0 # dp[i-2]: best two houses back (starts at 0)
prev1 = 0 # dp[i-1]: best one house back (starts at 0)
for num in nums:
# Current best: rob this house or skip it
curr = max(num + prev2, prev1)
prev2 = prev1 # Slide window forward
prev1 = curr
return prev1 # prev1 holds the answer after full scan
Point out the initialisation — both variables start at 0, not at any house value. This elegantly handles the base cases without a special check: on the first iteration, max(nums[0] + 0, 0) = nums[0], which is correct.
Visual Walkthrough
Tracing the two-variable solution for nums = [2, 7, 9, 3, 1]:
Final answer: 12 (rob houses 0, 2, 4 → 2 + 9 + 1 = 12)
Now tracing the DP array for the same input to show they match:
| i | nums[i] | dp[i−2] | dp[i−1] | rob = nums[i]+dp[i−2] | skip = dp[i−1] | dp[i] |
|---|---|---|---|---|---|---|
| 0 | 2 | — | — | — | — | 2 |
| 1 | 7 | 0 | 2 | — | — | 7 |
| 2 | 9 | 2 | 7 | 9+2=11 | 7 | 11 |
| 3 | 3 | 7 | 11 | 3+7=10 | 11 | 11 |
| 4 | 1 | 11 | 11 | 1+11=12 | 11 | 12 ★ |
Step 4: Highlight Edge Cases
“If there’s only one house, rob it — returnnums[0]. The two-variable solution handles this naturally: after one iteration,prev1 = nums[0]. No special case needed.”
“With two houses, rob the larger one — you can’t rob both. After two iterations, prev1 = max(nums[0], nums[1]). Again, the formula handles this without a special case.”
“If all houses have 0 money, the answer is 0. Every max(0+0, 0) stays 0 throughout. Returns 0 correctly.”
“e.g. [1, 2, 3, 4, 5] — you might expect to always rob the larger neighbour, but the optimal is alternating: rob indices 1, 3 → 2+4=6, or 0, 2, 4 → 1+3+5=9. The DP correctly picks the max at each step.”
“Starting bothprev1andprev2at 0 is a clean trick — it handles the base cases inside the loop without any special-casing. On the first iteration,max(nums[0] + 0, 0) = nums[0]. On the second,max(nums[1] + 0, nums[0]) = max(nums[1], nums[0]). Both correct.”
Step 5: State Time and Space Complexity
| Approach | Time | Space |
|---|---|---|
| Brute Force / Recursion | O(2ⁿ) | O(n) |
| DP Array | O(n) | O(n) |
| Two Variables ✓ | O(n) | O(1) |
“We visit each house exactly once. At each step we do a constant-time max comparison and two variable updates. We only store two integers regardless of n — O(1) space. This is the rolling window optimisation — recognising that dp[i] only depends on dp[i−1] and dp[i−2], so we don’t need the full array.”
Interview Checklist for House Robber
- Restate — “max sum of non-adjacent elements in an array”
- Strip the story — it’s a max non-adjacent subset sum problem
- Mention brute force O(2ⁿ) and dismiss it
- State the recurrence —
dp[i] = max(nums[i] + dp[i−2], dp[i−1]) - Explain both choices clearly — rob this house or skip it
- Show DP array approach first — easier to explain and verify
- Optimise to two variables — only need last two dp values
- Explain why prev2 and prev1 start at 0 — eliminates base case edge handling
- Handle single house and two house edge cases
- State O(n) time and O(1) space
- Ask before coding, don’t just dive in
Related Problems to Practice
If you can solve House Robber cleanly, try these next:
