337. 打家劫舍III

动态规划

class Solution {
    public int rob(TreeNode root) {

        int[] dp = robOrNot(root);

        return Math.max(dp[0], dp[1]);
    }

    /**
     * 对于每个节点来说,都有两个孩子,无法用一个dp[j]同时表达两个孩子共四种状态,因此需要定义一个数组分别存储偷与不偷的结果
     * 对每个节点定义一个数组,dp[0]表示不偷该节点时的最大金额,此时两个孩子都可以选择偷或者不偷,即dp[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1])
     * dp[1]表示偷该节点,此时两个孩子都不能偷,即dp[1] = root.val + left[0] + right[0]
     * 二者取最大值就是在该节点能偷的最大金额
     */
    public int[] robOrNot(TreeNode root){

        int[] dp = new int[2];

        /**
         * 如果是空节点,无论偷不偷都是0
         */
        if (root == null){
            return dp;
        }

        /**
         * 后序遍历
         * 从下往上根据子节点的状态来确定父节点
         */
        int[] left = robOrNot(root.left);
        int[] right = robOrNot(root.right);

        dp[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
        dp[1] = root.val + left[0] + right[0];

        return dp;
    }
}

/**
 * 时间复杂度 O(n)
 * 空间复杂度 O(logn)
 */

https://leetcode-cn.com/problems/house-robber-iii/

posted @ 2022-01-21 23:33  振袖秋枫问红叶  阅读(44)  评论(0)    收藏  举报