House Robber
Problem Statement
You’re a stealthy thief hitting a row of houses, each with some cash. You can’t rob adjacent houses due to security systems. Maximize your loot! This medium-level DP challenge is a heist planner’s dream—pick your targets wisely!
Example
Input: nums = [1, 2, 3, 1]
Output: 4 (rob 1+3)
Input: nums = [2, 7, 9, 3, 1]
Output: 12 (rob 2+9+1)
Input: nums = [2, 1, 1, 2]
Output: 4 (rob 2+2)
Code
Java
Python
JavaScript
public class Solution { public int rob(int[] nums) { if (nums.length == 0) return 0; if (nums.length == 1) return nums[0]; int[] dp = new int[nums.length]; dp[0] = nums[0]; dp[1] = Math.max(nums[0], nums[1]); for (int i = 2; i < nums.length; i++) { dp[i] = Math.max(dp[i-2] + nums[i], dp[i-1]); } return dp[nums.length-1]; } }
def rob(nums): if not nums: return 0 if len(nums) == 1: return nums[0] dp = [0] * len(nums) dp[0] = nums[0] dp[1] = max(nums[0], nums[1]) for i in range(2, len(nums)): dp[i] = max(dp[i-2] + nums[i], dp[i-1]) return dp[-1] # Example usage print(rob([1, 2, 3, 1])) # 4 print(rob([2, 7, 9, 3, 1])) # 12
function rob(nums) { if (!nums.length) return 0; if (nums.length === 1) return nums[0]; let dp = new Array(nums.length); dp[0] = nums[0]; dp[1] = Math.max(nums[0], nums[1]); for (let i = 2; i < nums.length; i++) { dp[i] = Math.max(dp[i-2] + nums[i], dp[i-1]); } return dp[nums.length-1]; } // Example usage console.log(rob([1, 2, 3, 1])); // 4 console.log(rob([2, 7, 9, 3, 1])); // 12
Explanation
- DP Insight: At each house, choose max of robbing it (plus loot from 2 houses back) or skipping it.
- Steps: dp[0] = first house, dp[1] = max of first two, then dp[i] = max(dp[i-2] + nums[i], dp[i-1]).
- Flow Example ([2,7,9,3,1]): dp[0]=2, dp[1]=7, dp[2]=11 (2+9), dp[3]=11, dp[4]=12 (11+1).
- Why It Works: Optimal substructure—each decision builds on prior max loot.
Note
Time complexity: O(n), Space complexity: O(n). A sneaky, profitable heist with DP finesse!