https://leetcode.com/problems/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:
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.
Naive:
/**
* 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:
unordered_map<TreeNode*, int> with_root;
unordered_map<TreeNode*, int> without_root;
int rob(TreeNode* root) {
return max(find_with_root(root), find_without_root(root));
// preorder(root);
// return 0;
}
void preorder(TreeNode* root){
if(root == NULL) {
cout << '#';
return;
}
preorder(root->left);
cout << root->val;
preorder(root->right);
}
int find_with_root(TreeNode* root){
if(root == NULL) return 0;
else{
// cout << "with: " << root->val << endl;
auto itr = with_root.find(root);
if(itr == with_root.end()){
with_root[root] = ((root->val) + find_without_root(root->left) + find_without_root(root->right));
return with_root[root];
}else{
return itr->second;
}
}
}
int find_without_root(TreeNode* root){
if(root == NULL) return 0;
else{
// cout << "without: " << root->val << endl;
auto itr = without_root.find(root);
if(itr == without_root.end()){
without_root[root] = (max(find_without_root(root->left), find_with_root(root->left))\
+ max(find_without_root(root->right), find_with_root(root->right)));
return without_root[root];
}else{
return itr->second;
}
}
}
};
酷:
class Solution {
public:
int rob(TreeNode* root) {
int l = 0, r = 0;
int res = canRob(root, l, r);
return res;
}
private:
int canRob(TreeNode *root, int& l, int& r){
if(root == nullptr) return 0;
if(root->left == nullptr && root->right == nullptr) return root->val;
int ll = 0, lr = 0;
int rl = 0, rr = 0;
l = canRob(root->left, ll, lr);
r = canRob(root->right, rl, rr);
return max(ll+lr+rl+rr+root->val,l+r);
}
};
更酷:
class Solution {
public:
int rob(TreeNode* root) {
return robDFS(root).second;
}
pair<int, int> robDFS(TreeNode* node){
if( !node) return make_pair(0,0);
auto l = robDFS(node->left);
auto r = robDFS(node->right);
int f2 = l.second + r.second;
int f1 = max(f2, l.first + r.first + node->val);
return make_pair(f2, f1);
}
};