Leetcode 337. House Robber III
The problem is defined as follows:
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 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.
[0, 10^4]
, and the value of each node is between [0, 10^4]
.To solve this problem, we will use Dynamic Programming with memoization. The key observation is that for each node, the thief has two choices:
We will recursively calculate the maximum amount of money that can be robbed for each case and use memoization to store intermediate results to avoid redundant calculations.
Here is a breakdown of the steps:
robHelper
that returns two values: the maximum amount robbed if the current node is not robbed, and the maximum amount if it is robbed.HashMap
to store the results of subproblems to optimize the performance.import java.util.HashMap;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public class Solution {
public int rob(TreeNode root) {
HashMap<TreeNode, Integer> memo = new HashMap<>();
return robHelper(root, memo);
}
private int robHelper(TreeNode node, HashMap<TreeNode, Integer> memo) {
if (node == null) return 0;
if (memo.containsKey(node)) return memo.get(node);
// Money when robbing the current node
int moneyWithRob = node.val;
if (node.left != null) {
moneyWithRob += robHelper(node.left.left, memo) + robHelper(node.left.right, memo);
}
if (node.right != null) {
moneyWithRob += robHelper(node.right.left, memo) + robHelper(node.right.right, memo);
}
// Money when not robbing the current node
int moneyWithoutRob = robHelper(node.left, memo) + robHelper(node.right, memo);
// Max money we can rob from this node
int result = Math.max(moneyWithRob, moneyWithoutRob);
memo.put(node, result);
return result;
}
}
The time complexity of this solution is O(N) where N is the number of nodes in the tree. This is because each node is visited once, and the results are stored and reused, thus avoiding redundant calculations.
Got blindsided by a question you didn’t expect?
Spend too much time studying?
Or simply don’t have the time to go over all 3000 questions?