二叉树 + 动态规划
本题与二叉树结合,首先看到树应该立刻想到树的四种遍历方式(前,中,后,层)
- 明确的是使用后序遍历。 因为要通过递归函数的返回值来做下一步计算。
- 通过递归左节点,得到左节点偷与不偷的金钱。
- 通过递归右节点,得到右节点偷与不偷的金钱。
所以本题dp数组就是一个长度为2的数组,下标为0记录不偷该节点所得到的的最大金钱,下标为1记录偷该节点所得到的的最大金钱
/**
* 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[] res = robAction1(root);
return Math.max(res[0], res[1]);
}
int[] robAction1(TreeNode root) {
// res[0]表示不偷当前节点时的最大金额,res[1]表示偷当前节点时的最大金额
int res[] = new int[2];
if (root == null)
return res;
// 后序遍历
int[] left = robAction1(root.left);
int[] right = robAction1(root.right);
// 不偷当前节点时的最大金额。这是通过取左子树和右子树偷或不偷的最大值之和
res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
// 偷当前节点时的最大金额。这是通过当前节点的值加上左右子树不偷时的最大金额
res[1] = root.val + left[0] + right[0];
return res;
}
}