113 路径总和2-中等
题目:
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
分析:
算法1:
这里采用深度优先搜索,当遍历到叶子节点且节点的值等于剩下的值,那么就直接追加结果,并返回。如果不是,递归遍历左右子树。
但是这里的写法相对麻烦一些,因为是自底向上的递推;其实可以采用自顶向下的递推,利用path记录已经遍历过的节点。详见算法2。
// date 2022/10/24
func pathSum(root *TreeNode, targetSum int) [][]int {
var dfs func(root *TreeNode, v int) ([][]int, bool)
dfs = func(root *TreeNode, v int) ([][]int, bool) {
if root == nil {
return nil, false
}
res := make([][]int, 0, 16)
if root.Left == nil && root.Right == nil && root.Val == v {
t := []int{root.Val}
res = append(res, t)
return res, true
}
v -= root.Val
l, ok1 := dfs(root.Left, v)
r, ok2 := dfs(root.Right, v)
if ok1 {
for i := 0; i < len(l); i++ {
t := make([]int, 0, 16)
t = append(t, root.Val)
t = append(t, l[i]...)
res = append(res, t)
}
}
if ok2 {
for i := 0; i < len(r); i++ {
t := make([]int, 0, 16)
t = append(t, root.Val)
t = append(t, r[i]...)
res = append(res, t)
}
}
if ok1 || ok2 {
return res, true
}
return nil, false
}
asn, _ := dfs(root, targetSum)
return asn
}
算法2:【推荐该算法】
同样采用深度优先搜索,path
记录已经遍历过的节点值。
当遍历到节点时,直接追加值到path中
如果遇到叶子节点且满足条件,直接将path追加到最终结果,
因为每次遍历,整个路径会变化,因为需要返回前将1中增加的值去掉。
// date 2022/10/24
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func pathSum(root *TreeNode, targetSum int) [][]int {
ans := make([][]int, 0, 16)
path := make([]int, 0, 16)
var dfs func(root *TreeNode, sum int)
dfs = func(root *TreeNode, sum int) {
if root == nil {
return
}
path = append(path, root.Val)
sum -= root.Val
defer func() {
path = path[:len(path)-1]
}()
if root.Left == nil && root.Right == nil && sum == 0 {
one := make([]int, len(path))
copy(one, path)
ans = append(ans, one)
return
}
dfs(root.Left, sum)
dfs(root.Right, sum)
}
dfs(root, targetSum)
return ans
}
最后更新于