[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: 递归穷举。比较本节点与孙节点之和、儿节点之和之间取最者。
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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表中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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: 对每个节点增加存储信息的位置,降低运算时间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /** * 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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++:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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++:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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++:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 题目汇总
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构