Overview
This is the circular variant of the classic house robber problem. All houses are arranged in a circle, meaning the first house is adjacent to the last house. You cannot rob two adjacent houses, and because of the circular arrangement, you cannot rob both the first and last houses.
Given an array nums representing the amount of money in each house, return the maximum amount you can rob without alerting the police.
Implement robCircular(nums).
Constraints
1 ≤ nums.length ≤ 1000 ≤ nums[i] ≤ 1000- House 0 and house n-1 are adjacent (circular).
- You cannot rob two adjacent houses.
- Aim for $O(n)$ time, $O(1)$ space.
Examples
robCircular([2, 3, 2]); // → 3 — cannot rob house 0 and house 2 (adjacent in circle), so rob house 1 robCircular([1, 2, 3, 1]); // → 4 — rob house 0 (1) + house 2 (3) robCircular([1, 2, 3]); // → 3 — rob house 2 only
Notes
- Key insight: since house 0 and house n-1 are adjacent, you can never rob both. So the answer is
max(rob(houses[0..n-2]), rob(houses[1..n-1]))— run the linear house robber on two sub-ranges and take the max. - Reuse the linear DP from the non-circular version as a helper.
Solution
Reveal solution
function robCircular(nums) {
if (nums.length === 1) return nums[0];
if (nums.length === 2) return Math.max(nums[0], nums[1]);
function robLinear(arr, lo, hi) {
let prev2 = 0, prev1 = 0;
for (let i = lo; i <= hi; i++) {
const curr = Math.max(prev1, prev2 + arr[i]);
prev2 = prev1;
prev1 = curr;
}
return prev1;
}
return Math.max(
robLinear(nums, 0, nums.length - 2),
robLinear(nums, 1, nums.length - 1)
);
}Resources
Neighborhood Theft (Circular)
Overview
This is the circular variant of the classic house robber problem. All houses are arranged in a circle, meaning the first house is adjacent to the last house. You cannot rob two adjacent houses, and because of the circular arrangement, you cannot rob both the first and last houses.
Given an array nums representing the amount of money in each house, return the maximum amount you can rob without alerting the police.
Implement robCircular(nums).
Constraints
1 ≤ nums.length ≤ 1000 ≤ nums[i] ≤ 1000- House 0 and house n-1 are adjacent (circular).
- You cannot rob two adjacent houses.
- Aim for $O(n)$ time, $O(1)$ space.
Examples
robCircular([2, 3, 2]); // → 3 — cannot rob house 0 and house 2 (adjacent in circle), so rob house 1 robCircular([1, 2, 3, 1]); // → 4 — rob house 0 (1) + house 2 (3) robCircular([1, 2, 3]); // → 3 — rob house 2 only
Notes
- Key insight: since house 0 and house n-1 are adjacent, you can never rob both. So the answer is
max(rob(houses[0..n-2]), rob(houses[1..n-1]))— run the linear house robber on two sub-ranges and take the max. - Reuse the linear DP from the non-circular version as a helper.
Solution
Reveal solution
function robCircular(nums) {
if (nums.length === 1) return nums[0];
if (nums.length === 2) return Math.max(nums[0], nums[1]);
function robLinear(arr, lo, hi) {
let prev2 = 0, prev1 = 0;
for (let i = lo; i <= hi; i++) {
const curr = Math.max(prev1, prev2 + arr[i]);
prev2 = prev1;
prev1 = curr;
}
return prev1;
}
return Math.max(
robLinear(nums, 0, nums.length - 2),
robLinear(nums, 1, nums.length - 1)
);
}