Approach (Reduce Circle to Two Linear Passes + O(1) DP State)
In House Robber II, houses form a circle, so the first and last houses are adjacent and cannot both be robbed.
We convert this circular constraint into two linear subproblems and take the maximum result. Let n denote the number of houses.
- Exclude first house → evaluate the inclusive range
[1 .. n-1]. - Exclude last house → evaluate the inclusive range
[0 .. n-2].
Let linearHouseRobber(start, end) denote the standard linear House Robber executed directly over the indices without slicing.
The final answer is max(linearHouseRobber(1, n-1), linearHouseRobber(0, n-2)).
Why the n = 1 Edge Case Needs Special Handling
When there is only one house (n = 1), that single house will not be part of either of the two linear ranges —
[1 .. n-1] or [0 .. n-2] — because both become empty.
As a result, the main algorithm would incorrectly skip it and return 0.
Therefore, we handle this case separately by directly returning nums[0].
Linear Subproblem (State & Transition)
-
State variables:
prevMax— best total robbed so far excluding the last evaluated house.
currMax— best total robbed so far. - Initialization:
prevMax = 0,currMax = 0. -
Transition (for each house
iin[start .. end]):- If we rob it (must skip the last evaluated one) → total =
prevMax + nums[i]. - If we skip it → total =
currMax. - Then
newMax = max(currMax, prevMax + nums[i])and roll forward:prevMax = currMax,currMax = newMax.
- If we rob it (must skip the last evaluated one) → total =
- Result:
currMaxafter the loop gives the optimal value for that range.
Why Two Cases Solve the Circle
Because the first and last houses are adjacent, robbing one forbids the other. By separately computing the optimal totals
for ranges [1 .. n-1] and [0 .. n-2], we ensure that both endpoints are never chosen together.
The overall maximum of the two linear results gives the optimal circular solution.