class Solution {
Map<TreeNode , Integer> g = new HashMap<TreeNode , Integer>();
Map<TreeNode , Integer> f = new HashMap<TreeNode , Integer>();
public int rob(TreeNode root) {
dfs(root);
return Math.max(f.getOrDefault(root , 0) , g.getOrDefault(root , 0));
}
public void dfs(TreeNode node){
if(node == null) return;
dfs(node.left);
dfs(node.right);
f.put(node , node.val + g.getOrDefault(node.left , 0) + g.getOrDefault(node.right , 0));
g.put(node , Math.max(f.getOrDefault(node.left , 0) , g.getOrDefault(node.left , 0)) + Math.max(f.getOrDefault(node.right , 0) , g.getOrDefault(node.right , 0)));//注意这个地方括号较多,不要扩错了
}
}
核心算法:dp+dfs(这题挺好的,既考了dp,又考了dfs)
1. 这题定义了两个dp:
f[node]表示以node为根的树,在不窃取node情况下,能够窃取的最多钱财。
g[node]表示以node为根的树,在窃取node情况下,能够窃取的最多钱财。
2. 转移方程:
f[node] = g[node.left] + g[node.right] + node.val(窃取node,则node左右孩子都不能窃取)
g[node] = Math.max(f[node.left] , g[node.left]) + Math.max(f[node.right] , g[node.right])(不窃取node,则node的左右孩子既可以窃取,也可以不窃取,选择窃取钱财最多的情况)
3. 初始:f[null] = 0
转移方程的迭代顺序按照深度优先遍历的顺序。