Problem
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security systems connected and it will automatically contact the police if two adjacent houses were broken into on the same night.
Given an integer array nums
representing the amount of money of each house, return the maximum amount of money you can rob tonight without alerting the police.
Examples
Example 1:
Input:
nums = [1,2,3,1]
Output:
4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
Total amount you can rob = 1 + 3 = 4.
Example 2:
Input:
nums = [2,7,9,3,1]
Output:
12
Explanation: Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1).
Total amount you can rob = 2 + 9 + 1 = 12.
Solution
Method 1 - Dynamic Programming with Memorization
Code
Java
public int rob(int[] nums) {
if (nums.length == 0) {
return 0;
}
int[] mem = new int[nums.length + 1];
Arrays.fill(mem, -1);
mem[0] = 0;
return helper(nums.length, mem, nums);
}
private int helper(int size, int[] mem, int[] nums) {
if (size<1) {
return 0;
}
if (mem[size] != -1) {
return mem[size];
}
//two cases
int firstSelected = helper(size - 2, mem, nums) + nums[nums.length - size];
int firstUnselected = helper(size - 1, mem, nums);
return mem[size] = Math.max(firstSelected, firstUnselected);
}
Method 2 - Dynamic Programming
The key is to find the relation dp[i] = Math.max(dp[i-1], dp[i-2]+nums[i])
.
Code
Java
public int rob(int[] nums) {
if (nums == null || 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];
}
Method 3 - DP without Extra Space 🏆
We can use two variables, rob1 and rob2, to track the maximum value so far as iterating the array. You can use the following example to walk through the code.
50 1 1 50
Code
Java
public int rob(int[] num) {
if (num == null || num.length == 0)
return 0;
int rob1 = 0;
int rob2 = 0;
// rob1, rob2, houseN, houseN+1
for (int num: nums) {
int temp = Math.max(rob1+num, rob2);
rob1 = rob2; // we are moving forward
rob2 = temp;
}
return rob2;
}