LC.337. 打家劫舍 III(树形DP&递归)
思路:树形 +递归。
1.考虑考虑某个结点选或不选的的子树最大值为
若选 ,则
若不选 ,则
然后递归下去就可以了。
用 映射。
```cpp
/**
* 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>f,g;
void dfs(TreeNode * x){
if(!x) return;
dfs(x->left);
dfs(x->right);
f[x]=x->val+g[x->left]+g[x->right];
g[x]=max(f[x->left],g[x->left])+max(f[x->right],g[x->right]);
}
int rob(TreeNode* rt) {
dfs(rt);
return max(f[rt],g[rt]);
}
};
用结构体优化。
/**
* 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:
struct node{
int f,g;
};
unordered_map<TreeNode* ,int>f,g;
node dfs(TreeNode * x){
if(!x) return {};
auto l=dfs(x->left);
auto r=dfs(x->right);
int f,g;
f=x->val+l.g+r.g;
g=max(l.f,l.g)+max(r.f,r.g);
return {f,g};
}
int rob(TreeNode* rt) {
auto ans=dfs(rt);
return max(ans.f,ans.g);
}
};
2.考虑选 后,变为 左儿子的左儿子,左儿子的右儿子,右儿子的左儿子,右儿子的右儿子的子树最大值之和。
不选 ,则为左儿子和右儿子的子树最大值之和也可以进行递归。
/**
* 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 dfs(TreeNode* x,int &l,int &r){
if(!x) return 0;
int ll,lr,rl,rr;ll=lr=rl=rr=0;
l=dfs(x->left,ll,lr);
r=dfs(x->right,rl,rr);
return max(x->val+ll+lr+rl+rr,l+r);
}
int rob(TreeNode* rt) {
int l=0,r=0;
return dfs(rt,l,r);
}
};