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.
原以为是相邻层之间不能选择,于是就有 了如下的代码。
/* * 借助两个队列来完成按层来取出树节点。 * */
public int rob(TreeNode root) {
if(root==null){
return 0;
}
if(root.left==null&&root.right==null){//只有一层
return root.val;
}
Queue<TreeNode> q1=new LinkedList<TreeNode>();
Queue<TreeNode> q2=new LinkedList<TreeNode>();
q1.add(root);
List<Integer> res=new ArrayList<Integer>();
// res.add(root.val);
while(!q1.isEmpty()){
int maxValue=0;
while(!q1.isEmpty()){
TreeNode node=q1.poll();
maxValue+=node.val;
if(node.left!=null){
q2.add(node.left);
}
if(node.right!=null){
q2.add(node.right);
}
}
//开始将这一层节点的和 与上面的倒数第2层和倒数第3层可能产生的最大值。
int len=res.size();
if(len<2){//第一层和第二层的节点和直接进入即可
res.add(maxValue);
}
else if(len==2){
maxValue+=res.get(len-2);
res.add(maxValue);
}
else if(len>=3){
maxValue+=Math.max(res.get(len-2),res.get(len-3));
res.add(maxValue);
}
// q1.addAll(q2);
// q2.clear();
while(!q2.isEmpty()){
q1.add(q2.poll());
}
}
return Math.max(res.get(res.size()-1), res.get(res.size()-2));
}
思路来源于:https://leetcode.com/discuss/95367/1ms-java-solution
解释如下:此题就是利用动态规划来做,当前节点产生的最大值要么是此节点参与后产生的,要么是此节点没有参与产生的。
实现代码如下:
public int rob(TreeNode root) {
int []maxValue=robHelper(root);
return Math.max(maxValue[0], maxValue[1]);
}
/* * 返回的数组长度为2,第一个存储的是 * */
private int[] robHelper(TreeNode root) {
if(root==null){
return new int[]{0,0};
}
//maxValue[0]用来存储根节点没有参与的最大值,而maxValue[1]则是存储这根节点参与了产生的最大值。
int[] maxValue=new int[2];
int[] leftMaxValue=robHelper(root.left);
int[] rightMaxValue=robHelper(root.right);
maxValue[0]=Math.max(leftMaxValue[1], leftMaxValue[0])+Math.max(rightMaxValue[1], rightMaxValue[0]);
maxValue[1]=root.val+leftMaxValue[0]+rightMaxValue[0];//既然root参与了,则root的左右节点就不能参与了。
return maxValue;
}