[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 题目汇总