题目原文:
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.
题目大意:
此题是Easy-题目26和Middle-题目58的变形,这次这个贼偷的是二叉树,每偷一个节点,它的父节点和子节点都不能偷了,求最大收益。
题目分析:
我们很熟悉的前两题都是使用动态规划,而这道题用的是深搜,深搜的返回结果是一个两个元素的数组profit,其中profit[0]代表偷当前节点的时候得到的最大收益,profit[1]代表不偷当前节点时获得的最大收益。那么每次搜索左右子树的最大收益记为leftprofit和rightprofit,并取:
profit[0]=leftProfit[1]+rightProfit[1]+root.val;
profit[1]=Math.max(leftProfit[0],leftProfit[1])+Math.max(rightProfit[0],rightProfit[1]);
直到遇到空节点返回new int[2].
源码:(language:java)
public class Solution {
public int rob(TreeNode root) {
int[] profit = dfs(root);
return Math.max(profit[0], profit[1]);
}
private int[] dfs(TreeNode root) {
int[] profit = new int[2];
// profit[0] stands for the maximum profit with robbing root, while profit[1] stands for the maximum profit without robbing root.
if(root!=null) {
int[] leftProfit = dfs(root.left);
int[] rightProfit = dfs(root.right);
profit[0] = leftProfit[1] + rightProfit[1] + root.val;
profit[1] = Math.max(leftProfit[0],leftProfit[1]) + Math.max(rightProfit[0], rightProfit[1]);
return profit;
}
return new int[2];
}
}
成绩:
1ms(统计信息还未显示)
Cmershen的碎碎念:
本题的递归之前的题较少接触,递归的关系不太容易看出来,其实递归的设计应该是考虑函数的入口参数和返回值以及函数的功能,而不是强调递推关系式(类似斐波那契数列的递归方法或者欧几里得算法求gcd),那样构思很多时候是想不出来的(比如本题)。