Leetcode337. House Robber 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.
解题分析
乍一看,这个问题表现出“最优子结构”的特点:如果我们想从当前的二叉树(根源)中抢夺最大的金额,我们当然希望我们可以对其左右子树做同样的事情。
因此,根据这个思路,我们来定义函数rob(root),它将返回我们可以抢夺以根为根的二叉树的最大金额;现在的关键是从解决其子问题,即如何从rob(root.left),rob(root.right)等等获取rob(root)。
显然上面的分析提出了一个递归的解决方案。而对于递归,总是有必要弄清楚以下两个属性:
终止条件:我们什么时候知道抢劫(根)的答案,而没有任何计算?当然,当树空了——我们没有什么可抢的,所以金额是零。
递归关系:即如何从rob(root.left),rob(root.right)等等获取rob(root)。从树根的角度来看,最后只有两个场景:根被抢劫或没有被抢劫。如果是这样,由于“我们不能抢夺任何两个直接关联的房子”的限制,下一层可用的子树就是四个“孙子树”(root.left.left,root.left.right ,root.right.left,root.right.right)。但是,如果root不被抢劫,则下一级可用子树就是两个“子树”(root.left,root.right)。我们只需要选择产生更多金钱的场景。
源代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int rob(TreeNode* root) {
if (root == NULL) {
return 0;
}
int val = 0;
if (root->left != NULL) {
val += rob(root->left->left) + rob(root->left->right);
}
if (root->right != NULL) {
val += rob(root->right->left) + rob(root->right->right);
}
return max(val + root->val, rob(root->left) + rob(root->right));
}
};
以上是我对这道问题的一些想法,有问题还请在评论区讨论留言~