House Robber Around a Circle

medium dp array

Problem

Houses sit in a circle (the last house is adjacent to the first). Each house holds some money. Picking two adjacent houses on the circle triggers an alarm. Maximize the total money taken.

Trick: the first and last house can never both be taken. So solve two linear subproblems — best across houses 0..n−2, and best across houses 1..n−1 — and return the larger. Each linear subproblem is the classic non-adjacent DP: dp[i] = max(dp[i−1], dp[i−2] + nums[i]).

Inputnums = [3, 7, 4, 9, 1]
Output16
Take houses 1 (7) and 3 (9). They are not adjacent, and together they sum to 16.

def rob(nums):
    n = len(nums)
    if n == 1:
        return nums[0]
    def linear(lo, hi):
        p2 = p1 = 0
        for i in range(lo, hi + 1):
            cur = max(p1, p2 + nums[i])
            p2, p1 = p1, cur
        return p1
    return max(linear(0, n - 2), linear(1, n - 1))
function rob(nums) {
  const n = nums.length;
  if (n === 1) return nums[0];
  function linear(lo, hi) {
    let prev2 = 0, prev1 = 0;
    for (let i = lo; i <= hi; i++) {
      const cur = Math.max(prev1, prev2 + nums[i]);
      prev2 = prev1; prev1 = cur;
    }
    return prev1;
  }
  return Math.max(linear(0, n - 2), linear(1, n - 1));
}
class Solution {
    int[] a;
    public int rob(int[] nums) {
        a = nums;
        int n = nums.length;
        if (n == 1) return nums[0];
        return Math.max(linear(0, n - 2), linear(1, n - 1));
    }
    int linear(int lo, int hi) {
        int p2 = 0, p1 = 0;
        for (int i = lo; i <= hi; i++) {
            int cur = Math.max(p1, p2 + a[i]);
            p2 = p1; p1 = cur;
        }
        return p1;
    }
}
int linear(vector<int>& nums, int lo, int hi) {
    int p2 = 0, p1 = 0;
    for (int i = lo; i <= hi; i++) {
        int cur = max(p1, p2 + nums[i]);
        p2 = p1; p1 = cur;
    }
    return p1;
}
int rob(vector<int>& nums) {
    int n = nums.size();
    if (n == 1) return nums[0];
    return max(linear(nums, 0, n - 2), linear(nums, 1, n - 1));
}
Time: O(n) Space: O(1)