[LeetCode] 337. House Robber III 打家劫舍 III

The thief has found himself a new place for his thievery again. There is only one entrance to this area, called the "root." Besides the root, each house has one and only one parent house. After a tour, the smart thief realized that "all houses in this place forms a binary tree". It will automatically contact the police if two directly-linked houses were broken into on the same night.

Determine the maximum amount of money the thief can rob tonight without alerting the police.

Example 1:

     3
    / \
   2   3
    \   \ 
     3   1

Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.

Example 2:

     3
    / \
   4   5
  / \   \ 
 1   3   1

Maximum amount of money the thief can rob = 4 + 5 = 9.

Credits:
Special thanks to @dietpepsi for adding this problem and creating all test cases.

198. House Robber 和 213. House Robber II 的拓展,这回小偷又找了一个新的偷盗场所。这片区域只有一个入口,叫做“根”。除了根以外,每一个房间有且仅有一个父级房间。在踩点之后,聪明的盗贼发现“所有的房间形成了一棵二叉树”。如果两个有边直接相连的房间在同一晚上都失窃,就会自动联络警察。求在不惊动警察的情况下最多可以偷到的钱数。

Java: 递归穷举。比较本节点与孙节点之和、儿节点之和之间取最者。

public int rob(TreeNode root) {  
        if (root == null) return 0;  
        int val = 0;  
        if(root.left!=null){  
            val += rob(root.left.left);  
            val += rob(root.left.right);  
        }  
        if(root.right!=null){  
            val += rob(root.right.left);  
            val += rob(root.right.right);  
        }  
        return Math.max(val+root.val,(rob(root.left)+rob(root.right)));  
   }  

Java: 改进递归,节省每一步计算中间值,因为儿节点又是孙节点的父节点,会重复计算,所以把计算的中间值存储到hash表中。

public int get(TreeNode root,HashMap<TreeNode,Integer> map) {  
    if (root == null) return 0;  
    if (map.containsKey(root)) return map.get(root);  
    int val = 0;  
    if(root.left!=null){  
        val += get(root.left.left,map);  
        val += get(root.left.right,map);  
    }  
    if(root.right!=null){  
        val += get(root.right.left,map);  
        val += get(root.right.right,map);  
    }  
    int x = Math.max(val+root.val,(get(root.left,map)+get(root.right,map)));  
    map.put(root,x);  
    return x;  
      
public int rob(TreeNode root) {  
    return get(root,new HashMap<TreeNode,Integer>());          
} 

Java: 对每个节点增加存储信息的位置,降低运算时间。

/** 
 * Definition for a binary tree node. 
 * public class TreeNode { 
 *     int val; 
 *     TreeNode left; 
 *     TreeNode right; 
 *     TreeNode(int x) { val = x; } 
 * } 
 */  
  
class Solution {  
    public int[] get(TreeNode n){  
        if(n==null) return new int[2];  
        int[] lstrategy = get(n.left);//0表示不取,1表示取  
        int[] rstrategy = get(n.right);//  
        int[] nstrategy = new int[2];  
        nstrategy[0] = Math.max(lstrategy[0],lstrategy[1])+Math.max(rstrategy[0],rstrategy[1]); ; //strategy[0]表式不取本节点的策略取值,strategy[1]表式取本节点与孙节点的策略取值  
        nstrategy[1] = n.val + lstrategy[0] + rstrategy[0];      
        return nstrategy;  
    }  
          
   public int rob(TreeNode root) {  
    if (root == null) return 0;  
    int[] result = get(root);  
       return Math.max(result[0],result[1]);     
   }  
}  

Java:

public class Solution {
    public int rob(TreeNode root) {
        int[] num = dfs(root);
        return Math.max(num[0], num[1]);
    }
    private int[] dfs(TreeNode x) {
        if (x == null) return new int[2];
        int[] left = dfs(x.left);
        int[] right = dfs(x.right);
        int[] res = new int[2];
        res[0] = left[1] + right[1] + x.val;
        res[1] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
        return res;
    }
}  

Python:

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)
            return (root.val + left[1] + right[1], max(left) + max(right))
        
        return max(robHelper(root))

C++:

class Solution {
public:
    int rob(TreeNode* root) {
        unordered_map<TreeNode*, int> m;
        return dfs(root, m);
    }
    int dfs(TreeNode *root, unordered_map<TreeNode*, int> &m) {
        if (!root) return 0;
        if (m.count(root)) return m[root];
        int val = 0;
        if (root->left) {
            val += dfs(root->left->left, m) + dfs(root->left->right, m);
        }
        if (root->right) {
            val += dfs(root->right->left, m) + dfs(root->right->right, m);
        }
        val = max(val + root->val, dfs(root->left, m) + dfs(root->right, m));
        m[root] = val;
        return val;
    }
};

C++:

class Solution {
public:
    int rob(TreeNode* root) {
        vector<int> res = dfs(root);
        return max(res[0], res[1]);
    }
    vector<int> dfs(TreeNode *root) {
        if (!root) return vector<int>(2, 0);
        vector<int> left = dfs(root->left);
        vector<int> right = dfs(root->right);
        vector<int> res(2, 0);
        res[0] = max(left[0], left[1]) + max(right[0], right[1]);
        res[1] = left[0] + right[0] + root->val;
        return res;
    }
};

C++:

class Solution {
public:
    int rob(TreeNode* root) {
        int l = 0, r = 0;
        return helper(root, l, r);
    }
    int helper(TreeNode* node, int& l, int& r) {
        if (!node) return 0;
        int ll = 0, lr = 0, rl = 0, rr = 0;
        l = helper(node->left, ll, lr);
        r = helper(node->right, rl, rr);
        return max(node->val + ll + lr + rl + rr, l + r);
    }
};

  

类似题目:

[LeetCode] 198. House Robber 打家劫舍

[LeetCode] 213. House Robber II 打家劫舍 II

  

All LeetCode Questions List 题目汇总

 

posted @ 2018-03-26 08:05  轻风舞动  阅读(356)  评论(0编辑  收藏  举报