标签:结点 right III 337 getMaxMoney 力扣 null root left
题目:
在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为“根”。 除了“根”之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警。计算在不触动警报的情况下,小偷一晚能够盗取的最高金额。
示例 1:
输入: [3,2,3,null,3,null,1] 3 / \ 2 3 \ \ 3 1 输出: 7 解释: 小偷一晚能够盗取的最高金额 = 3 + 3 + 1 = 7.
示例2:
输入: [3,4,5,1,3,null,1] 3 / \ 4 5 / \ \ 1 3 1 输出: 9 解释: 小偷一晚能够盗取的最高金额 = 4 + 5 = 9.
分析:
透过现象看本质,其实就是邻近节点的值不能同时获取,求出所能获取的最大和。对于二叉树问题,一般从最简单的情况去分析,然后进行一系列的重复性递归操作即可解决。我们将二叉树分为三个部分,第一部分是父亲结点,第二部分是两个左右子结点,第三部分是两个左右子节点的所有子树。为什么要分成这几个部分呢?那是因为根据题意可知,父亲结点的值和其左右子结点的值是不可兼得的,左右子结点的值和它们各自的孩子结点的值是不可兼得的,但是左右子结点的父亲结点的值和左右子结点的孩子结点的值可以兼得,因为第一部分的父亲结点一定和其左右子结点的所有子树结点不直接相连,所以无论第三部分的子树们如何选定具体的结点,只需保证第三部分都是基于它们那些子树情况下的最大和即可(这就涉及了递归),最终我们将第一部分和第三部分相加与第二部分的值进行比较,哪个大就返回哪个即可。
其中第三部分是不一定存在的,如果第三部分不存在,那么就只用第一部分和第二部分进行比较。
代码:
public int rob(TreeNode root) { if (root == null){ return 0; } getMaxMoney(root); return getMaxMoney(root); } private int getMaxMoney(TreeNode root){ if (root == null){ return 0; } if (root.left == null && root.right == null){ return root.val; } int childMoney = getMaxMoney(root.left) + getMaxMoney(root.right); int fatherMoney = root.val; if (root.left != null){ fatherMoney += getMaxMoney(root.left.left); fatherMoney += getMaxMoney(root.left.right); } if (root.right != null){ fatherMoney += getMaxMoney(root.right.left); fatherMoney += getMaxMoney(root.right.right); } return Math.max(fatherMoney,childMoney); }
标签:结点,right,III,337,getMaxMoney,力扣,null,root,left 来源: https://www.cnblogs.com/yxym2016/p/13472858.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。