Intuition
At each house you either skip it (keep the best total up to the previous house) or rob it (its money plus the best total up to two houses back). dp[i] = max(dp[i-1], dp[i-2] + nums[i]).
Explanation
Idea
Standing at house i, you face a binary choice:
- Skip house
i: your best is whatever you had through housei-1→dp[i-1]. - Rob house
i: you can't have robbedi-1, so add its money to your best through housei-2→dp[i-2] + nums[i].
Take the better of the two:
dp[i] = max(dp[i-1], dp[i-2] + nums[i])
Only the last two values matter, so we track them in two rolling variables and use O(1) space.
Algorithm
prev = 0(best two houses back),curr = 0(best one house back).- For each
xinnums:prev, curr = curr, max(curr, prev + x). - Return
curr.
Worked example: [2,7,9,3,1]
| house | nums[i] | skip = dp[i-1] | rob = dp[i-2]+nums[i] | dp[i] |
|---|---|---|---|---|
| 0 | 2 | 0 | 0 + 2 | 2 |
| 1 | 7 | 2 | 0 + 7 | 7 |
| 2 | 9 | 7 | 2 + 9 | 11 |
| 3 | 3 | 11 | 7 + 3 | 11 |
| 4 | 1 | 11 | 11 + 1 | 12 |
Maximum = 12 (rob houses 0, 2, 4: 2 + 9 + 1).
Complexity
- Time: O(n).
- Space: O(1) with rolling variables.
Implementation
class Solution {
public int rob(int[] nums) {
int prev = 0, curr = 0;
for (int x : nums) {
int next = Math.max(curr, prev + x);
prev = curr;
curr = next;
}
return curr;
}
}