337. 打家劫舍 III
思路
首先可以把题目看为一棵树,小偷不能盗取拥有父子关系的节点。
1.我们首先模拟两个函数,分别代表偷当前节点与不偷当前节点,用来对应相应的金额。f代表偷取,g代表不透取当前节点对应的金额。
2.采用后续遍历的方法拆分题目,即左右根。
3.最终答案应是偷取根节点或者不偷取根节点中的最大值就是所求。
下面请看代码与注释。
/*
* Definition for a binary tree node.
* 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;
* }
* }
*/
//上边是基本注释
class Solution {
/* f、g 模拟了两个函数*/
Map<TreeNode, Integer> f = new HashMap<>(); //选中节点时对应的map
Map<TreeNode, Integer> g = new HashMap<>(); //未选中节点对应的map
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));
//不取当前节点时为:左节点(取/不取)中的最大值 + 右节点(取/不取)中的最大值 注意:此时包含2*2=4种情况
g.put(node,Math.max(g.getOrDefault(node.left,0) , f.getOrDefault(node.left,0)) + Math.max(g.getOrDefault(node.right,0) ,
f.getOrDefault(node.right,0)));
}
}
简单介绍:getOrDefault(key,defaultValue);
含义:从map中取key的值,如果不为null,则正常取,如果为null,则为defaultValue的值。
如有错误:请批评指正!谢谢。