/**
* robRoot = root.val + rob(root.left.left) + rob(root.left.right) + rob(root.right.left) + rob(root.right.right)
* notRobRoot = rob(root.left) + rob(root.right);
*
* return Max(robRoot, notRobRoot)
*/
public int rob(TreeNode root) {
if (root == null) {
return 0;
}
int robRoot = root.val;
if (root.left != null) {
robRoot += rob(root.left.left) + rob(root.left.right);
}
if (root.right != null) {
robRoot += rob(root.right.left) + rob(root.right.right);
}
int notRobRoot = rob(root.left) + rob(root.right);
return Math.max(robRoot, notRobRoot);
}
- 方法二、递归 + 记忆 (dp 解法),注意 因为要比较每个TreeNode的是否相同(地址和数值都要一样,即TreeNode本身),所以 一定不要重写(没必要)自定义的类TreeNode中的equals和hashcode方法。
public int rob(TreeNode root) {
Map<TreeNode, Integer> dp = new HashMap<>();
return robWithMemory(root, dp);
}
private int robWithMemory(TreeNode root, Map<TreeNode, Integer> dp) {
if (root == null) {
return 0;
}
if (dp.containsKey(root)) {
return dp.get(root);
}
int robRoot = root.val;
if (root.left != null) {
robRoot += robWithMemory(root.left.left, dp) + robWithMemory(root.left.right, dp);
}
if (root.right != null) {
robRoot += robWithMemory(root.right.left, dp) + robWithMemory(root.right.right, dp);
}
int notRobRoot = robWithMemory(root.left, dp) + robWithMemory(root.right, dp);
int result = Math.max(robRoot, notRobRoot);
dp.put(root, result);
return result;
}
- 方法三、为了解决方法一重复计算的问题,需要重新定义rob函数的含义:定义rob(root)返回含有2个元素的一维数组dp, 其中dp[0]: rob this node, dp[1]: not rob this node.
/**
* robRoot = root.val + rob(root.left)[1] + rob(root.right)[1]
* notRobRoot = Max(rob(root.left)[0], rob(root.left)[1]) + Max(rob(root.right)[0], rob(root.right)[1])
*
* return Max(robRoot, notRobRoot)
*/
public int rob(TreeNode root) {
int[] dp = subRob(root);
return Math.max(dp[0], dp[1]);
}
private int[] subRob(TreeNode root) {
if (root == null) {
return new int[2];
}
int[] left = subRob(root.left);
int[] right = subRob(root.right);
int robRoot = root.val + left[1] + right[1];
int notRobRoot = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
return new int[]{robRoot, notRobRoot};
}