LeetCode 337. 打家劫舍 III

小偷又发现一个新的可行窃的地点。 这个地区只有一个入口,称为“根”。 除了根部之外,每栋房子有且只有一个父房子。 一番侦察之后,聪明的小偷意识到“这个地方的所有房屋形成了一棵二叉树”。 如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警。

在不触动警报的情况下,计算小偷一晚能盗取的最高金额。

示例 1:

     3
    / \
   2   3
    \   \ 
     3   1

能盗取的最高金额 = 3 + 3 + 1 = 7.

示例 2:

     3
    / \
   4   5
  / \   \ 
 1   3   1

能盗取的最高金额 = 4 + 5 = 9.

思路:在代码里面

java版:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 
 *关键在于记录点偷过没
 */
// import java.util.HashMap;
class Solution {
    
    public static Map trueCache = new HashMap();
    public static Map falseCache = new HashMap();
    
    public static int robot(TreeNode root,boolean canRob){
        
        //bianjie
        if(root == null){
            return 0;
        }
        
        if(canRob && trueCache.containsKey(root)){
            return trueCache.get(root);
        }
        if(!canRob && falseCache.containsKey(root)){
            return falseCache.get(root);
        }
        
        int ans = 0;
        if(canRob){
            ans = Math.max(ans,root.val + robot(root.left,false) + robot(root.right,false));
        }
        
        ans = Math.max(ans,robot(root.left,true) + robot(root.right,true));
        
        if(canRob){
            trueCache.put(root,ans);
        }
        if(!canRob){
            falseCache.put(root,ans);
        }
        return ans;
    }
       
    public int rob(TreeNode root) {
        trueCache.clear();
        falseCache.clear();
        return robot(root,true);
    }
}

// class Solution {
//     public int rob(TreeNode root) {
//         return robDFS(root)[1];
//     }

//     private int[] robDFS(TreeNode node) {
//         int[] res = new int[2];
//         if (node == null) return res;
//         int[] l = robDFS(node.left);
//         int[] r = robDFS(node.right);
//         res[0] = l[1] + r[1];
//         res[1] = Math.max(res[0], l[0] + r[0] + node.val);
//         return res;
//     }
// }

 

python版:

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
#############1种是该节点值加上不包含左子节点和右子节点的返回值之和,另一种是左右子节点返回值之和不包含当期节点值,取两者的较大值返回即可
class Solution:
    def rob(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        truecache = {}
        falsecache = {}        
        def robot(root,canRob,truecache,falsecache):#关键在于这个点偷过没
            if root == None:
                return 0
            ans = 0
            

            if canRob and (root in truecache):#如果可以偷,并且可以偷得缓存字典里面有最大金额数
                return truecache[root]
            if (canRob == False) and (root in falsecache):
                return falsecache[root]
            
            if canRob:
                ans = max(ans,root.val + robot(root.left,False,truecache,falsecache) + robot(root.right,False,truecache,falsecache))
            
            ans = max(ans,robot(root.left,True,truecache,falsecache) + robot(root.right,True,truecache,falsecache))#根节点不偷什么时候都可以
            
            if canRob:
                truecache[root] = ans
            if canRob == False:
                falsecache[root] = ans

            return ans
        
        
        return robot(root,True,truecache,falsecache)
    
    
# class Solution(object):
#     def rob(self, root):
#         """
#         :type root: TreeNode
#         :rtype: int
#         """
        
#         def robHelper(root):
#             if not root:
#                 return (0, 0)
#             left, right = robHelper(root.left), robHelper(root.right)#rob左右两个子节点
#             return (root.val + left[1] + right[1], max(left) + max(right))#如果rob当前节点,那就抢左右子节点的的子节点返回的最大值,如果不rob当前就rob左右子节点返回的最大值
        
#         return max(robHelper(root))
            

 

你可能感兴趣的:(LeetCode 337. 打家劫舍 III)