My Eighty-third Page - 打家劫舍Ⅲ - By Nicolas

这篇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的取值得到最后的数值。

希望上面的分析和代码可以帮助到小伙伴们~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值