两个状态数组,且对于树的问题跟数组不一样,状态数组用的是哈希表,键是树结点的指针,值是以这个结点为根节点的树可以偷到的钱的最高金额。两个状态数组,分别表示今晚偷了根节点和没有偷根节点,y表示偷了根节点的情况下偷的最高金额,n表示没有偷根节点的情况下偷到的最高金额。
当今晚偷了根节点,那么肯定没有偷其两个孩子。即:
y[root] = g[root->left] + g[root->right]
当今晚没有偷根节点,那么可以偷其两个孩子,也可以没偷,即:
g[root] = max(y[root->left], g[root->left]) + max(y[root->right], g[root->right])
/**
* 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:
// 哈希表的键是某个结点的指针,值是以该结点为根节点的树能偷到的最高金额,其中哈希表y中表示偷了根节点,n表示没有偷根节点
unordered_map<TreeNode*, int> y, n; // y表示选择这个节点,n表示不选这个节点
void dfs(TreeNode *root){
if(!root) return;
dfs(root->left);
dfs(root->right);
y[root] = root->val + n[root->left] + n[root->right];
n[root] = max(y[root->left], n[root->left]) + max(y[root->right], n[root->right]);
}
int rob(TreeNode* root) {
if(!root) return 0;
dfs(root);
return max(y[root], n[root]);
}
};