337. House Robber III

  • 方法一、递归: 找到递归关系,以及终止条件
    /**
     * robRoot = root.val + rob(root.left.left) + rob(root.left.right) + rob(root.right.left) + rob(root.right.right)
     * notRobRoot = rob(root.left) + rob(root.right);
     *
     * return Max(robRoot, notRobRoot)
     */
    public int rob(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int robRoot = root.val;
        if (root.left != null) {
            robRoot += rob(root.left.left) + rob(root.left.right);
        }
        if (root.right != null) {
            robRoot += rob(root.right.left) + rob(root.right.right);
        }
        int notRobRoot = rob(root.left) + rob(root.right);
        return Math.max(robRoot, notRobRoot);
    }
  • 方法二、递归 + 记忆 (dp 解法),注意 因为要比较每个TreeNode的是否相同(地址和数值都要一样,即TreeNode本身),所以 一定不要重写(没必要)自定义的类TreeNode中的equals和hashcode方法。
    public int rob(TreeNode root) {
        Map<TreeNode, Integer> dp = new HashMap<>();
        return robWithMemory(root, dp);
    }

    private int robWithMemory(TreeNode root, Map<TreeNode, Integer> dp) {
        if (root == null) {
            return 0;
        }
        if (dp.containsKey(root)) {
            return dp.get(root);
        }

        int robRoot = root.val;
        if (root.left != null) {
            robRoot += robWithMemory(root.left.left, dp) + robWithMemory(root.left.right, dp);
        }
        if (root.right != null) {
            robRoot += robWithMemory(root.right.left, dp) + robWithMemory(root.right.right, dp);
        }
        int notRobRoot = robWithMemory(root.left, dp) + robWithMemory(root.right, dp);
        int result = Math.max(robRoot, notRobRoot);

        dp.put(root, result);
        return result;
    }
  • 方法三、为了解决方法一重复计算的问题,需要重新定义rob函数的含义:定义rob(root)返回含有2个元素的一维数组dp, 其中dp[0]: rob this node, dp[1]: not rob this node.
    /**
     * robRoot = root.val + rob(root.left)[1] + rob(root.right)[1]
     * notRobRoot = Max(rob(root.left)[0], rob(root.left)[1]) + Max(rob(root.right)[0], rob(root.right)[1])
     *
     * return Max(robRoot, notRobRoot)
     */
    public int rob(TreeNode root) {
        int[] dp = subRob(root);
        return Math.max(dp[0], dp[1]);
    }

    private int[] subRob(TreeNode root) {
        if (root == null) {
            return new int[2];
        }
        int[] left = subRob(root.left);
        int[] right = subRob(root.right);
        int robRoot = root.val + left[1] + right[1];
        int notRobRoot = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
        return new int[]{robRoot, notRobRoot};
    }
原文地址:https://www.cnblogs.com/lasclocker/p/11488110.html