House Robber(I, II, III) with Dynamic programming in Java

2017-09-22

In this article, I am going to illustrate three House Robber problem on LeetCode with dynamic Programming.

See the link here:
198 House Robber I 213 House Robber II 337 House Robber III

House Robber I:

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 system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

First, we consider there are two possible situation: 1. The previous house has been robbed 2. The previous house has not been robbed.

If the previous house has been robbed, we will not be able to rob the current house. So we need to skip this house.

If the previous house has not been robbed, we may rob this current house, or we skip this house.

1
2
3
4
5
6
7
8
9
10
public int rob(int[] nums){
int prevNo = 0;
int prevYes = 0;
for(int n: nums){
int tmp = prevNo;
prevNo = Math.max(prevNo, prevYes); // don't rob current house
prevYes = n + tmp; //rob the current house
}
return Math.max(prev,prevYes);
}

House Robber II

After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. This time, all houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street.

Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

The only difference in II is now, the array is a circle, which means the last one is connected with the first one.

Almost same as the previous one, but we need to seperate the problem into two cases: 1. If we rob the first one, we will not be able to rob the last one 2. If we haven’t rob the first one, we may rob the last one.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Make a slight change to the previous one, we define the specific range for calculating the max value
public int helper(int[] nums, int start, int end){
int prevNo = 0;
int prevYes = 0;
for(int i = start; i <= end; i++){
int tmp = prevNo;
prevNo = Math.max(prevNo, prevYes);
prevYes = nums[start] + prevNo;
}
return Math.max(prevNo, prevYes);
}
public int rob(int[] nums){
return Math.max(helper(nums,0,nums.length-2),helper(nums,1,nums.length-1));
}

House Robber III

The thief has found himself a new place for his thievery again. There is only one entrance to this area, called the “root.” Besides the root, each house has one and only one parent house. After a tour, the smart thief realized that “all houses in this place forms a binary tree”. It will automatically contact the police if two directly-linked houses were broken into on the same night.

Determine the maximum amount of money the thief can rob tonight without alerting the police.

Example 1:

1
2
3
4
5
3
/ \
2 3
\ \
3 1

Maximum amount of money the thief can rob = 3+3+1=7. (First and last level)

Example 2:

1
2
3
4
5
3
/ \
4 5
/ \ \
1 3 1

Maximum amount of money the thief can rob = 4+5=9 (Second level)

The idea of this problem is same as the first one, what we need to change here is do the depth first search. We create an array {ele1, ele2}. ele1 stands for the thief does not rob the current house, ele2 stands for the thief rob the current house.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public int[] dfs(TreeNode root){
if(root == null){
return new int[2];
}
int[] left = dfs(root.left);
int[] right = dfs(root.right);
int[] ans = new int[2];
ans[0] = Math.max(left[0],left[1])+Math.max(right[0], right[1]);
ans[1] = root.val +left[0]+right[0];
return ans;
}
public int rob(TreeNode root) {
int[] ans = dfs(root);
return Math.max(ans[0],ans[1]);
}

Comments: