1、 哈希表 money,存储当前节点可打劫的最大金额
2、回溯:感觉做题过程中,应该用什么算法有思路了,但是具体编写代码,理清程序逻辑的过程却存在问题。之后重点提升这一方面。其实一看到二叉树就想到了回溯,但是我的问题在于每次都想要先把回溯(动态规划也有这种情况)的各个细节想清楚,然后再理清思路开始编写代码,思路很容易绕进去就乱了。但感觉回溯其实可以把递归函数的返回值当作已知值,思考如何在这个值已知的情况下,分类讨论各个情况(主要还是把问题所有可能的情况进行分类讨论)
参数:当前的节点 返回值:以该节点为根节点可以抢的最多钱
- 当前节点为空,直接返回0
- 1、左子树不为空:计算左子树的左右子树为根最多抢多少的和
- 2、右子树不为空:计算右子树的左右子树为根最多抢多少的和
- 3、计算左右子树为根最多抢多少的和
- 对比3与1+1+当前节点值,取较大值作为当前节点能够抢的最多钱,返回
注意:以上方法提交时,结果正确,但超出要求的时间范围,考虑到递归过程中存在大量的重复计算,所以采用空间换时间的策略,维护哈希表money[*TreeNode]int,存储以各个节点为根时抢到的最多钱。
Go
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func rob(root *TreeNode) int {
var money map[*TreeNode]int=make(map[*TreeNode]int)
var dfs func(r *TreeNode) int
var getMax func(a, b int) int
getMax=func(a, b int) int {
if a>=b{
return a
}else{ return b }
}
dfs=func(r *TreeNode) int {
if r==nil{ return 0 }
if v, ok:=money[r]; ok{ return v }
val:=0
if r.Left!=nil{ val+=dfs(r.Left.Left)+dfs(r.Left.Right) }
if r.Right!=nil{ val+=dfs(r.Right.Left)+dfs(r.Right.Right) }
val=getMax(r.Val+val, dfs(r.Left)+dfs(r.Right))
money[r]=val
return val
}
return dfs(root)
}