337. House Robber III
Description:
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.
Difficulty:Medium
Example:
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.
方法:Deep First Search
- Time complexity : O ( n ) O\left ( n\right ) O(n)
- Space complexity :
O
(
n
)
O\left ( n \right )
O(n)
思路:
针对一个节点记录两个值,第一个值是包含此节点的最大数,第二个值是不包含此节点的最大数,这样能极大减少递归次数
class Solution {
public:
int rob(TreeNode* root) {
return helper(root).first;
}
pair<int, int> helper(TreeNode* root){
if(!root) return make_pair(0, 0);
pair<int, int> left = helper(root->left);
pair<int, int> right = helper(root->right);
int max_without_self = left.first + right.first;
int max_may_with_self = max((root->val + left.second + right.second),
max_without_self);
return make_pair(max_may_with_self, max_without_self);
}
};
第一版,很傻的代码,时间复杂度: O ( 2 n ) O\left ( 2^n\right ) O(2n)
class Solution {
public:
int rob(TreeNode* root) {
if(!root) return 0;
if(!root->left && !root->right)
return root->val;
if(root->left && root->right)
return max((root->val +
rob(root->left->left) +
rob(root->left->right) +
rob(root->right->left) +
rob(root->right->right)),
rob(root->left) + rob(root->right)
);
if(!root->left)
return max((root->val +
rob(root->right->left) +
rob(root->right->right)),
rob(root->right)
);
if(!root->right)
return max((root->val +
rob(root->left->left) +
rob(root->left->right)),
rob(root->left)
);
return 0;
}
};
第二版,简洁,但是还是慢
class Solution {
public:
int rob(TreeNode* root) {
if(!root) return 0;
int t1 = 0;
int t2 = root->val;
t1 = rob(root->left) + rob(root->right);
if(root->left)
t2 += rob(root->left->left) + rob(root->left->right);
if(root->right)
t2 += rob(root->right->left) + rob(root->right->right);
return max(t1, t2);
}
};