House-Robber-III
第60天。
今天的题目是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.
之前有刷过House robber
,上次是一道dp
的题目,这次看起来有点像是dp
的题目,但是其实不是。
我们考虑当前节点root
,我们有两种选择:
- 不偷
root
:这意味着我们对root
的孩子没有限制(即可以偷也可以不偷)。 - 偷
root
:这意味着我们不能偷root
的孩子。
从上面的分析可以看出,对于一个节点,我们可能需要返回两个值,一个是偷了root
所得到的money
,一个是不偷root
所得到的money
.我们可以用一个结构体来表示:
1 | typedef struct { |
假设我们现在得到了root
左孩子和右孩子的Ret
了,我们现在要构建root
本身的Ret
.显然rob = left.norob + right.norob + root->val
.然后还有norob
,这个很容易就写成norob = left.rob + right.rob
,这样写就假定了rob > norob
的,在上面的分析中,我们是说我们对root
的孩子没有限制,既然没有限制,就可以偷也可以不偷,所以norob = max(left.rob,left.norob) + max(right.rob,right.norob)
.
1 | int rob(TreeNode* root) { |
dicuss
中的解法大都是这个思路,只是写法不同而已,有一个写法比较有趣:
1 | public int rob(TreeNode root) { |