树-337. 打家劫舍 III-PYTHON/JAVA

树-337. 打家劫舍 III-PYTHON/JAVA_第1张图片

解法一–最优子结构(递归)

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def rob(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root:
            return 0;
        money = root.val
        if root.left != None:
            money += (self.rob(root.left.left) + self.rob(root.left.right))
        
        if root.right != None:
            money += (self.rob(root.right.left) + self.rob(root.right.right))
        
        return max(money,self.rob(root.left) + self.rob(root.right))
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public int rob(TreeNode root) {
        if (root == null) return 0;
        int money = root.val;
        if (root.left != null){
            money += (rob(root.left.left) + rob(root.left.right));
        }

        if (root.right != null){
            money += (rob(root.right.left) + rob(root.right.right));
        }

        return Math.max(money,rob(root.left) + rob(root.right));
    }
}

解法二–基于解法一利用中间缓存结构保存可重复使用的数据提高速度

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def rob(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        Interval = dict()
        return self.robhelper(root,Interval)
    
    def robhelper(self,root,Interval):
        if root == None: return 0
        if root in Interval.keys(): return Interval.get(root)
        money = root.val

        if root.left != None:
            money += (self.robhelper(root.left.left,Interval) + self.robhelper(root.left.right,Interval))
        if root.right != None:
            money += (self.robhelper(root.right.left,Interval) + self.robhelper(root.right.right,Interval))
        
        result = max(money,self.robhelper(root.left,Interval) + self.robhelper(root.right,Interval))
        Interval[root] = result
        return result
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public int rob(TreeNode root) {
        HashMap<TreeNode,Integer>  memo = new HashMap<>();
        return robhelper(root,memo);
    }

    public int robhelper(TreeNode root,HashMap<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 += (robhelper(root.left.left,memo) + robhelper(root.left.right,memo));
        }
        if (root.right != null){
            money += (robhelper(root.right.left,memo) + robhelper(root.right.right,memo));
        }

        int result = Math.max(money,robhelper(root.left,memo) + robhelper(root.right,memo));
        memo.put(root,result); //将计算结果放入哈希表中
        return result;

    }
}

解法三–最终+最灵活

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public int rob(TreeNode root) {
        int[] result = robhelper(root);
        return Math.max(result[0],result[1]);//返回根节点偷和不偷的两种结果之间最大的那一个
    }

    public int[] robhelper(TreeNode root){
        if (root == null) return new int[2];//返回匿名变量
        int[] result = new int[2];

        int[] left = robhelper(root.left);//递归的去深入创建局部的左右孩子偷与不偷的情况对应的数组
        int[] right = robhelper(root.right);

        result[0] = Math.max(left[0],left[1]) + Math.max(right[0],right[1]);//当前节点不偷,那么就比对左右子节点偷与不偷的大小情况进行选择--亮点在这里
        result[1] = left[0] + right[0] + root.val;//当前节点如果偷,那么就是将子节点的不偷情况加上当前节点的值

        return result;//最终返回到根节点偷与不偷的两种情况结果
    }
}

你可能感兴趣的:(LEETCODE)