198. House Robber
Link: https://leetcode.com/problems/house-robber/
Description
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.
Approach
- If there is only one house, return the money of the house.
- Else, create an array
dp
of the same length as thenums
array to store the maximum amount of money that can be robbed up to that house. - Initialize
dp[0]
withnums[0]
anddp[1]
with the maximum ofnums[0]
andnums[1]
. - Iterate through the
nums
from the third house to the last house:- Select the maximum amout of money between robbing the previous house
dp[i - 1]
and robbing from the current housenums[i]
and the two houses backdp[i - 2]
.
- Select the maximum amout of money between robbing the previous house
Solution
class Solution {
public int rob(int[] nums) {
if (nums.length == 1)
return nums[0];
int[] dp = new int[nums.length];
dp[0] = nums[0];
dp[1] = Math.max(dp[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];
}
}
213. House Robber II
Link: https://leetcode.com/problems/house-robber-ii/
Description
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, adjacent houses have a security system 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.
Approach
- If there is only one house, return the money of the house.
- Split the robber into two situations, one excludes the first house, the other one excludes the last house and return the maximum of the two situations.
- Initialize a recursive function with parameters
nums
,start
(the start of the array),end
(the end of the array). - Call the function with the two mentioned situations above and return the maximum value.
- Inside the recursive function:
- if there is only one processed house in the range, return the value of the house.
- Else, create an array
dp
of the same length asnums
to store the maximum amount of money that can be robbed up to each house within the given range. - Initialize
dp[0]
withnums[start]
anddp[1]
with the maximum ofnums[start]
andnums[start + 1]
. - Iterate through the
nums
in the given range starting from the third house:- Select the maximum amout of money between robbing the previous house
dp[i - 1]
and robbing from the current housenums[i]
and the two houses backdp[i - 2]
.
- Select the maximum amout of money between robbing the previous house
- Return
dp[end]
.
Solution
class Solution {
public int rob(int[] nums) {
if (nums.length == 1)
return nums[0];
return Math.max(robAction(nums, 0, nums.length - 2), robAction(nums, 1, nums.length - 1));
}
private int robAction(int[] nums, int start, int end) {
if (start == end)
return nums[start];
int[] dp = new int[nums.length];
dp[start] = nums[start];
dp[start + 1] = Math.max(dp[start], nums[start + 1]);
for (int i = start + 2; i <= end; i++)
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
return dp[end];
}
}
337. House Robber III
Link: https://leetcode.com/problems/house-robber-iii/
Description
The thief has found himself a new place for his thievery again. There is only one entrance to this area, called 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 form a binary tree. It will automatically contact the police if two directly-linked houses were broken into on the same night.
Given the root
of the binary tree, return the maximum amount of money the thief can rob without alerting the police.
Approach
- Initialize a
result
array whereresult[0]
represents the maximum amount of money that can be obtained without robbing the current node, andresult[1]
represents the maximum amount of money that can be obtained with robbing the current node. - Initialize a recursive function with parameter
root
(represents the curent house) and call it with the first house. - Inside the recursive function:
- Initialize a
result
array whereresult[0]
represents the maximum amount of money that can be obtained without robbing the current node, andresult[1]
represents the maximum amount of money that can be obtained with robbing the current node. - If the node is null, return the
result
array. - Call the function with the left child and right child, obtain respective
result
arrays. result[0]
is the maximum between the maximum amount from the left subtree without and with robbing the left child, and the maximum amount from the right subtree without and with robbing the right child.result[1]
is the addtion of the value of current node, maximum amount without robbing the left child and maximum amount without robbing the right child.- Return
result
.
- Initialize a
Solution
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int rob(TreeNode root) {
int[] result = new int[2];
result = robAction(root);
return Math.max(result[0], result[1]);
}
private int[] robAction(TreeNode root) {
int[] result = new int[2];
if (root == null)
return result;
int[] left = robAction(root.left);
int[] right = robAction(root.right);
result[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
result[1] = root.val + left[0] + right[0];
return result;
}
}