力扣337题(树形dp、二叉树后序遍历)

  1. 小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root 。除了 root 之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果 两个直接相连的房子在同一天晚上被打劫 ,房屋将自动报警。给定二叉树的 root 。返回 在不触动警报的情况下 ,小偷能够盗取的最高金额

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/house-robber-iii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  1. 该题是树形dp的入门题,树形dp就是在树的结构上进行动态规划。
  2. 这个题目中,与每个房子即二叉树中的每个节点直接相连的节点只有每个节点的孩子节点,因此每个节点的状态(偷与不偷)都跟它们的孩子节点的状态有关,因此该题需要用二叉树的后序遍历来解决。.
  3. 二叉树的后序遍历通过递归来实现,用一个长度为2的数组来记录状态的转移,数组的第一元素表示不偷当前节点所能得到的最高金额,第二个元素表示偷当前节点所能得到的最高金额。
  4. 具体代码及过程如下
/**
 * 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 = robTree(root);
        return Math.max(res[0], res[1]);
        
    }

    public int[] robTree(TreeNode cur) {
        if (cur == null) // 递归终止条件,当遇到空节点,偷与不偷都返回0
            return new int[]{0,0};
        int[] left = robTree(cur.left); // 左子树的盗窃情况
        int[] right = robTree(cur.right); // 右子树的盗窃情况
        int val1 = Math.max(left[0], left[1]) + Math.max(right[0], right[1]); // 当不偷当前节点时,当前节点的左右孩子节点都能偷,但是要考虑能获取金额最大的方式
        int val2 = cur.val + left[0] + right[0]; // 当偷当前节点时,当前节点的左右孩子节点都不能偷
        return new int[]{val1, val2};
    }
}

你可能感兴趣的:(刷题,leetcode,算法)