时间复杂度:O(n²)
解题思路
主要算法就是借助于先序遍历的深度优先算法。每遍历到一个结点,就更新路径总和,并将该结点值加到路径中,然后判断该结点是否为叶子结点,如果是叶子结点并且路径总和与目标路径总和相等,就将路径追加到结果切片中,但如果不相等就从路径中删除该结点值并返回。由于在遍历过程中并不会遍历到空结点,所以在开始下一轮递归前判断左右孩子是否为空,只有不为空才能继续递归左孩子或右孩子。递归完成后将从路径中删除该结点值,也就是说,每次返回前都要从路径中删除该结点值。
AC代码
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func pathSum(root *TreeNode, targetSum int) [][]int {
res:=[][]int{}
if root==nil{
return res
}
t:=[]int{}
var dfs func(*TreeNode,int)
dfs=func(root *TreeNode,sum int){
sum+=root.Val
t=append(t,root.Val)
if root.Left==nil&&root.Right==nil{
if sum==targetSum{
res=append(res,append([]int{},t...))
}
t=t[:len(t)-1]
return
}
if root.Left!=nil{
dfs(root.Left,sum)
}
if root.Right!=nil{
dfs(root.Right,sum)
}
t=t[:len(t)-1]
}
dfs(root,0)
return res
}
感悟
一开始想根据遍历到的结点为空时且路径总和为目标值再更新结果切片,但是会造成结果切片的每条路径都有两个,原因是每个叶子结点的左右孩子都是空结点。