LeetCode 337 打家劫舍 3

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)
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值