[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 題目匯總

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com