Skip to content

213. House Robber II 👍

  • Time: $O(n)$
  • Space: $O(n) \to O(1)$
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
 public:
  int rob(vector<int>& nums) {
    if (nums.empty())
      return 0;
    if (nums.size() == 1)
      return nums[0];

    auto rob = [&](int l, int r) {
      int prev1 = 0;  // dp[i - 1]
      int prev2 = 0;  // dp[i - 2]

      for (int i = l; i <= r; ++i) {
        const int dp = max(prev1, prev2 + nums[i]);
        prev2 = prev1;
        prev1 = dp;
      }

      return prev1;
    };

    return max(rob(0, nums.size() - 2), rob(1, nums.size() - 1));
  }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
  public int rob(int[] nums) {
    if (nums.length == 0)
      return 0;
    if (nums.length == 1)
      return nums[0];
    return Math.max(rob(nums, 0, nums.length - 2), rob(nums, 1, nums.length - 1));
  }

  private int rob(int[] nums, int l, int r) {
    int prev1 = 0; // dp[i - 1]
    int prev2 = 0; // dp[i - 2]

    for (int i = l; i <= r; ++i) {
      final int dp = Math.max(prev1, prev2 + nums[i]);
      prev2 = prev1;
      prev1 = dp;
    }

    return prev1;
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class Solution:
  def rob(self, nums: list[int]) -> int:
    if not nums:
      return 0
    if len(nums) < 2:
      return nums[0]

    def rob(l: int, r: int) -> int:
      dp1 = 0
      dp2 = 0

      for i in range(l, r + 1):
        temp = dp1
        dp1 = max(dp1, dp2 + nums[i])
        dp2 = temp

      return dp1

    return max(rob(0, len(nums) - 2),
               rob(1, len(nums) - 1))