对于这种树形结构,应该很容易想到使用递归的方法,这里的难点在于递归的时候相邻点不能同时访问,因此我写成了第一种做法,也ac了,但是这样并不好,因为它对很多点都会重复遍历。
于是在网上看到了第二种写法,很优雅,它定义了一个数据结构,对于当前节点,如果不使用该节点会拿多少钱,如果使用该节点又会多少钱。
很显然,对于一个节点而言,比如root,
那么rootMoney.notUse = 左子节点的最大值+右子节点的最大值(无所谓左子节点和右子节点是否使用)
rootMoney.use = root.val + 左子节点的notUse + 右子节点的NotUse。
这种代码结构感觉会更清秀一些。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
//使用递归的算法
public class Solution {
public int rob(TreeNode root) {
if(root == null)
return 0;
int rootVal = root.val;
int leftHand = 0,rightHand = 0;
if(root.left != null){
int l1 = rob(root.left.left);
int l2 = rob(root.left.right);
rootVal += l1+l2;
leftHand = rob(root.left);
}
if(root.right != null){
int r1 = rob(root.right.left);
int r2 = rob(root.right.right);
rootVal += r1+r2;
rightHand = rob(root.right);
}
if(leftHand + rightHand > rootVal)
return leftHand+ rightHand;
return rootVal;
}
}
代码2【elegant】
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
class Money{
int notUse;//不使用该节点时的money
int use;//使用该节点时的money
Money(){
notUse = 0;
use = 0;
}
}
public int rob(TreeNode root) {
Money rootMoney = getMoney(root);
return Math.max(rootMoney.notUse,rootMoney.use);
}
private Money getMoney(TreeNode root){
if(root == null)
return new Money();
Money leftMoney = getMoney(root.left);
Money rightMoney = getMoney(root.right);
Money rootMoney = new Money();
rootMoney.use = root.val + leftMoney.notUse + rightMoney.notUse;
rootMoney.notUse = Math.max(leftMoney.notUse,leftMoney.use) + Math.max(rightMoney.notUse,rightMoney.use);
return rootMoney;
}
}