动态规划
class Solution {
public int rob(TreeNode root) {
int[] dp = robOrNot(root);
return Math.max(dp[0], dp[1]);
}
/**
* 对于每个节点来说,都有两个孩子,无法用一个dp[j]同时表达两个孩子共四种状态,因此需要定义一个数组分别存储偷与不偷的结果
* 对每个节点定义一个数组,dp[0]表示不偷该节点时的最大金额,此时两个孩子都可以选择偷或者不偷,即dp[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1])
* dp[1]表示偷该节点,此时两个孩子都不能偷,即dp[1] = root.val + left[0] + right[0]
* 二者取最大值就是在该节点能偷的最大金额
*/
public int[] robOrNot(TreeNode root){
int[] dp = new int[2];
/**
* 如果是空节点,无论偷不偷都是0
*/
if (root == null){
return dp;
}
/**
* 后序遍历
* 从下往上根据子节点的状态来确定父节点
*/
int[] left = robOrNot(root.left);
int[] right = robOrNot(root.right);
dp[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
dp[1] = root.val + left[0] + right[0];
return dp;
}
}
/**
* 时间复杂度 O(n)
* 空间复杂度 O(logn)
*/
https://leetcode-cn.com/problems/house-robber-iii/