这篇page是针对leetcode上的337.打家劫舍Ⅲ所写的。小尼先简单的说明一下这道题的意思,就是我们这次偷取的房子是一个二叉树的形式表现出来的,这次引起报警的条件是我们如果连续偷了父节点和子节点,那么我们就会引发报警,我们需要求出的就是可以在不报警的条件下,我们可以偷取到的最大的金额为多少。
小尼先简单的说明一下这道题的解题思路,首先其实就是需要分析递归三部曲:
1、确定递归函数的参数和返回值:这里我们要求一个节点偷于不偷的两个状态所得到的金钱,那么返回值就是一个长度为2的数组,所以我们在这里设定dp数组以及下标的含义:下标为0记录不偷节点所得到的最大金钱,下标为1记录偷该节点所得到的最大金钱
2、确定终止条件:如果我们遇到了空节点,无论偷还是不偷都是0
3、确定遍历顺序:我们采用后续便利
小尼接下来拉一下这道题的集体的代码:
public int rob1(TreeNode root) {
Map<TreeNode, Integer> memo = new HashMap<>();
return robAction(root, memo);
}
int robAction(TreeNode root, Map<TreeNode, Integer> memo) {
if (root == null)
return 0;
if (memo.containsKey(root))
return memo.get(root);
int money = root.val;
if (root.left != null) {
money += robAction(root.left.left, memo) + robAction(root.left.right, memo);
}
if (root.right != null) {
money += robAction(root.right.left, memo) + robAction(root.right.right, memo);
}
int res = Math.max(money, robAction(root.left, memo) + robAction(root.right, memo));
memo.put(root, res);
return res;
}
首先呢上面这一段代码没有运用小尼上述的dp定义一个人数组进行比较偷或是不偷,这个方法就是直接采取递归的方法对我们的值进行对应的相加记录,最后我们只需要max取值即可
接下来小尼拉一下采取dp数组分析0、1情况的代码:
public int rob3(TreeNode root) {
int[] res = robAction1(root);
return Math.max(res[0], res[1]);
}
int[] robAction1(TreeNode root) {
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;
}
}
这一段就是我们采取分析,我们定义的res数组,如果里面的元素取0的时候就是我们此时的root值是不偷的,如果元素取1代表着我们的root是一定会取的,所以我们在取值的时候,我们不断的递归取值,最后在主方法里进行一个max的取值得到最后的数值。
希望上面的分析和代码可以帮助到小伙伴们~~~