这道题主要就是想到要枚举出所有可的情况,那么每一个节点只有两种可能,一个是偷一个是不偷,偷的前提是它的父节点没有被偷所以需要传入父节点的信息(有无被偷),过程中采用记忆化搜索的逻辑,存储已经出现的情况。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
/*
这道题采用的是递归+记忆化搜索的逻辑,利用递归枚举出所有可能的情况,然后通过两个hashmap来存放已经遍历过的所有可能的情况(包括该位置true和false的),每次取递归前查找map中有无对应的内容,有就直接使用。
*/
int rob(TreeNode* root) {
return find_max(root,false);
}
unordered_map<TreeNode*,int> check_true;
unordered_map<TreeNode*,int> check_false;
int find_max(TreeNode* root,bool last)//某种意义算前序了
{
int val1=0,val2=0;
if(!last)//根没有偷,说明这个节点可以偷
{
if(check_true.find(root)!=check_true.end())val1=check_true[root];//先查找有无记录
else{//没有记录就递归去计算
val1=root->val;
if(root->left)val1+=find_max(root->left,true);
if(root->right)val1+=find_max(root->right,true);
check_true[root]=val1;
}
}
if(check_false.find(root)!=check_false.end())val2=check_false[root];//先查找有无记录
else{//没有记录就递归去计算
if(root->left)val2+=find_max(root->left,false);
if(root->right)val2+=find_max(root->right,false);
check_false[root]=val2;
}
return max(val1,val2);//最后返回偷这个节点和不偷这个节点中的较大值
}
};