例题:
题解:
https://leetcode-cn.com/problems/house-robber-iii/solution/san-chong-fang-fa-jie-jue-shu-xing-dong-tai-gui-hu/
先看懂这篇博客 此博客的第三个方法的递归思路 和之前几天的学习中
递归思想是一样的 再好好琢磨一下。
睡了一晚 再做做这个题好像思路清晰了一些
1 首先dp 一般是数组 循环一直保留着以谁为结尾时的结果最优解 所以他是一直在以上面结尾最优解的情况下 再累加上自身时 求最优解
2 然后这个题中 树形dp 没法用数组 用了个递归返回值数组 不断地累加 最后累加到根节点 返回最优解 关键就是递归上(跟day2的路径总和问题思想一样)
AC:
哈希表空间:
class Solution {
Map<TreeNode, Integer> f = new HashMap<TreeNode, Integer>();
Map<TreeNode, Integer> g = 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)));
}
}
纯递归
package 二叉树;
public class 树形dp {
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val,TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
public int rob(TreeNode root) {
int[] result=dfs(root);
return Math.max(result[0],result[1]);
}
public int[] dfs(TreeNode root){
int [] res=new int[2];
if(root==null) {
return new int[2];
}
int left[]=dfs(root.left);
int right[]=dfs(root.right);
res[0]=Math.max(left[0],left[1])+Math.max(right[0],right[1]);
res[1]=left[0]+right[0]+root.val;
return res;
}
}
ps:向如上的这个递归特点 root为null时返回空值 这也就是累加的数据来源
一开始用清空res数据 方便这一层存入数据 然后累加上去 不会冲突 因为递归栈的节点还未出栈 可以理解他还保存着属于自己的那个值