House Robber III
LeetCode 337 | Difficulty: Mediumβ
MediumProblem 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.
Example 1:

Input: root = [3,2,3,null,3,null,1]
Output: 7
Explanation: Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.
Example 2:

Input: root = [3,4,5,1,3,null,1]
Output: 9
Explanation: Maximum amount of money the thief can rob = 4 + 5 = 9.
Constraints:
-
The number of nodes in the tree is in the range
[1, 10^4]. -
0 <= Node.val <= 10^4
Topics: Dynamic Programming, Tree, Depth-First Search, Binary Tree
Approachβ
Dynamic Programmingβ
Break the problem into overlapping subproblems. Define a state (what information do you need?), a recurrence (how does state[i] depend on smaller states?), and a base case. Consider both top-down (memoization) and bottom-up (tabulation) approaches.
Optimal substructure + overlapping subproblems (counting ways, min/max cost, feasibility).
Tree DFSβ
Traverse the tree recursively (or with a stack). At each node, decide: what information do I need from the left/right subtrees? Process: go left β go right β combine results. Consider preorder, inorder, or postorder traversal based on when you need to process the node.
Path problems, subtree properties, tree structure manipulation.
Solutionsβ
Solution 1: C# (Best: 100 ms)β
| Metric | Value |
|---|---|
| Runtime | 100 ms |
| Memory | 25 MB |
| Date | 2019-03-21 |
/**
* Definition for a binary tree node.
* public class TreeNode {
* public int val;
* public TreeNode left;
* public TreeNode right;
* public TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public int Rob(TreeNode root) {
return RobSub(root, new Dictionary<TreeNode, int> ());
}
public int RobSub (TreeNode root, Dictionary<TreeNode, int> map)
{
if(root == null) return 0;
if(map.ContainsKey(root)) return map[root];
int val = 0;
if(root.left != null)
{
val += RobSub(root.left.left, map) + RobSub(root.left.right, map);
}
if(root.right != null)
{
val += RobSub(root.right.left, map) + RobSub(root.right.right, map);
}
val = Math.Max(val + root.val, RobSub(root.left, map) + RobSub(root.right, map));
map.Add(root, val);
return val;
}
}
Complexity Analysisβ
| Approach | Time | Space |
|---|---|---|
| Dynamic Programming | ||
| Tree Traversal |
Interview Tipsβ
- Discuss the brute force approach first, then optimize. Explain your thought process.
- Define the DP state clearly. Ask: "What is the minimum information I need to make a decision at each step?"
- Consider if you can reduce space by only keeping the last row/few values.
- Consider: "What information do I need from each subtree?" β this defines your recursive return value.