Solving tips
- The circle only means houses 0 and n-1 can't both be robbed, so run the linear House Robber twice and take the max.
- Solve max(rob_line(nums[:-1]), rob_line(nums[1:])) - once excluding the last house, once excluding the first.
- Special-case n==1 up front, since slicing off an end would empty the array and lose the only value.
- Don't grab both ends: [5,1,1,5] gives 6, not 10; target O(n) time, O(1) space per pass with two rolling scalars.
Problem
Youβre given an integer array nums where nums[i] is the amount of money stashed in house i. The houses are arranged in a circle, so the first and last houses are neighbors. A silent alarm trips if you rob two adjacent houses on the same night. Return the maximum total you can rob without ever hitting two adjacent houses.
Because the houses form a circle, robbing house 0 forbids robbing house n-1, and vice versa.
Examples
nums = [2,3,2]β3β you cannot rob houses 0 and 2 (they are adjacent on the circle), so the best single choice is house 1 for3.nums = [1,2,3,1]β4β rob house 0 (1) and house 2 (3); houses 0 and 3 are not both taken, so no wrap conflict.nums = [1,2,3]β3β take just house 2.
Constraints
1 <= nums.length <= 1000 <= nums[i] <= 1000
Think about it first
Hint 1
Forget the circle for a moment. If the houses were in a straight line, what's the max you can rob? That's the classic House Robber recurrence: at each house you either skip it (keep the best so far) or take it (add it to the best from two houses back).Hint 2
The only thing the circle adds is: house 0 and house n-1 can't both be robbed. So split into two independent line problems β one that excludes the last house, one that excludes the first β and take the better.Hint 3
Answer =max(rob_line(nums[0 .. n-2]), rob_line(nums[1 .. n-1])), where rob_line is the linear House Robber. Handle n == 1 as a special case (a single house has no neighbor to conflict with).