題目鏈接
tag:
- Medium;
question:
??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:
Input: [3,2,3,null,3,null,1]
3
/ \
2 3
\ \
3 1
Output: 7
Explanation: Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.
Example 2:
Input: [3,4,5,1,3,null,1]
3
/ \
4 5
/ \ \
1 3 1
Output: 9
Explanation: Maximum amount of money the thief can rob = 4 + 5 = 9.
思路:
??這道題是之前那兩道House Robber和House Robber ||的拓展俏橘,這個小偷又偷出新花樣了,沿著二叉樹開始偷煌抒,題目中給的例子看似好像是要每隔一個偷一次妄痪,但實(shí)際上不一定只隔一個辖众,比如如下這個例子:
4
/
1
/
2
/
3
??下面這種解法由網(wǎng)友edyyy提供。這里的helper函數(shù)返回當(dāng)前結(jié)點(diǎn)為根結(jié)點(diǎn)的最大rob的錢數(shù)载荔,里面的兩個參數(shù)l
和r
表示分別從左子結(jié)點(diǎn)和右子結(jié)點(diǎn)開始rob盾饮,分別能獲得的最大錢數(shù)。在遞歸函數(shù)里面懒熙,如果當(dāng)前結(jié)點(diǎn)不存在丐谋,直接返回0。否則我們對左右子結(jié)點(diǎn)分別調(diào)用遞歸函數(shù)煌珊,得到l
和r
号俐。另外還得到四個變量,ll和lr表示左子結(jié)點(diǎn)的左右子結(jié)點(diǎn)的最大rob錢數(shù)定庵,rl和rr表示右子結(jié)點(diǎn)的最大rob錢數(shù)吏饿。那么我們最后返回的值其實(shí)是兩部分的值比較,其中一部分的值是當(dāng)前的結(jié)點(diǎn)值加上ll, lr, rl, 和rr這四個值蔬浙,這不難理解猪落,因?yàn)閾屃水?dāng)前的房屋,那么左右兩個子結(jié)點(diǎn)就不能再搶了畴博,但是再下一層的四個子結(jié)點(diǎn)都是可以搶的笨忌;另一部分是不搶當(dāng)前房屋,而是搶其左右兩個子結(jié)點(diǎn)俱病,即l+r的值官疲,返回兩個部分的值中的較大值即可,代碼如下:
/**
* 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) {
int l = 0, r = 0;
return helper(root, l, r);
}
int helper(TreeNode* node, int& l, int& r) {
if (!node)
return 0;
int ll = 0, lr = 0, rl = 0, rr = 0;
l = helper(node->left, ll, lr);
r = helper(node->right, rl, rr);
return max(node->val + ll + lr + rl + rr, l + r);
}
};