LeetCode 437 路径总和 |||(需要考虑优化)

本文探讨了一种解决二叉树中寻找特定路径和问题的方法,主要涉及回溯策略。通过暴力穷举思路构建递归函数,但注意到存在重复计算和高时空复杂度的问题。提出了利用公共变量记录满足条件的路径数,以及使用哈希表存储已遍历过的父辈路径和来优化。然而,由于节点值可能为负数,单纯的剪枝操作难以实现。最后,Go语言实现的代码展示了基本的暴力穷举方法,但效率较低。
摘要由CSDN通过智能技术生成

 1、数据结构

2、回溯:看到二叉树,要计算满足条件的路径个数的时候,首先就想到了回溯。为了理清回溯的整体思路,思考暴力穷举的情况下如何遍历所有路径和。

暴力穷举:从每一个节点出发,计算当前节点到各个子树节点所有路径,按照路径长度进行遍历。

重复的计算:会对子树的路径和进行重复计算。例如,对于题目途中10的节点,长为3的路径包含以下几种情况 [10,5,3][10,5,2][10,-3,11],这其中包含了节点5,-3对应的长为2的路径。

根据暴力穷举的思路构建递归思路:

1)维护如下公共变量:res(int)记录满足条件的路径数

2)回溯过程,对二叉树进行层序遍历,传递如下参数

(1)当前树的根节点:*TreeNode

(2)当前根节点的父节点到当前节点的路径和:fathers map[*TreeNode]int 类型

3)遍历到一个树节点:判断当前节点值是否==targetSum

(1)是:res++

(2)否:res不做改变

(3)不论是否:遍历fathers,对应的路径和依次相加,判断结果是否==targetSum,同时用相加的新sum更新原有sum,是的话res++

(4)之后将当前节点添加到fathers中,判断左右节点是否为空,不为空的进行递归,传入参数为非空子节点以及更新后的fathers哈希表

注意:在传递map等内容的时候,注意指针类型的修改会跨函数保留

Go:基本也算暴力穷举,最后的通过结果可太差了

func pathSum(root *TreeNode, targetSum int) int {
    var res int=0
    var seq func(r *TreeNode, s map[*TreeNode]int)
    seq=func(r *TreeNode, s map[*TreeNode]int){
        if r==nil{ return }
        // fmt.Println(r.Val, s, res)

        var sumMap map[*TreeNode]int=make(map[*TreeNode]int)
        if r.Val==targetSum{ res++ }
        for k, v:=range s{ 
            if r.Val+v==targetSum{ res++ } 
            sumMap[k]=r.Val+v
        }
        sumMap[r]=r.Val
        seq(r.Left, sumMap)
        seq(r.Right, sumMap)
    }
    seq(root, make(map[*TreeNode]int))
    return res
}

考虑如何降低时空复杂度

1)在遍历的过程中进行剪枝操作,但是因为二叉树中各个节点的值可能为负数,即使当前路径和>targetSum,后续相加后依然有可能==targetSum

2)使用共有空间,记录已经遍历过的父辈路径和

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值