这是树的第16篇算法,力扣链接。
给你二叉树的根节点
root
和一个整数目标和targetSum
,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22 输出:[[5,4,11,2],[5,8,4,5]]
比较上一节返回布尔值就可以了,这回可能复杂一点,我们需要额外存储路径信息,不过其实还好,我们增加一个空间来存储每次遍历的路径就好。
func pathSum(root *TreeNode, targetSum int) [][]int {
if root == nil {
return nil
}
var result [][]int
stack := []*TreeNode{root}
sumStack := []int{root.Val}
paths := [][]int{{root.Val}}
for len(stack) > 0 {
node := stack[len(stack)-1]
stack = stack[:len(stack)-1]
currentSum := sumStack[len(sumStack)-1]
sumStack = sumStack[:len(sumStack)-1]
path := paths[len(paths)-1]
paths = paths[:len(paths)-1]
if node.Left == nil && node.Right == nil && currentSum == targetSum {
result = append(result, append([]int{}, path...))
}
if node.Left != nil {
stack = append(stack, node.Left)
sumStack = append(sumStack, currentSum+node.Left.Val)
newPath := append([]int{}, path...)
newPath = append(newPath, node.Left.Val)
paths = append(paths, newPath)
}
if node.Right != nil {
stack = append(stack, node.Right)
sumStack = append(sumStack, currentSum+node.Right.Val)
newPath := append([]int{}, path...)
newPath = append(newPath, node.Right.Val)
paths = append(paths, newPath)
}
}
return result
}
这里可以尝试递归来解决问题:
func pathSum(root *TreeNode, targetSum int) [][]int {
var result [][]int
var path []int
findPaths(root, targetSum, path, &result)
return result
}
func findPaths(node *TreeNode, sum int, path []int, result *[][]int) {
if node == nil {
return
}
path = append(path, node.Val)
if node.Left == nil && node.Right == nil && node.Val == sum {
*result = append(*result, append([]int(nil), path...))
} else {
findPaths(node.Left, sum-node.Val, path, result)
findPaths(node.Right, sum-node.Val, path, result)
}
// path = path[:len(path)-1] // 这行代码是多余的,因为每次递归都会复制path
}
广度优先算法和深度优先算法逻辑一样,只不过取出数据的顺序不同:
func pathSum(root *TreeNode, targetSum int) [][]int {
var result [][]int
if root == nil {
return result
}
queue := []*TreeNode{root}
paths := [][]int{{root.Val}}
sums := []int{root.Val}
for len(queue) > 0 {
node := queue[0]
queue = queue[1:]
path := paths[0]
paths = paths[1:]
sum := sums[0]
sums = sums[1:]
if node.Left == nil && node.Right == nil && sum == targetSum {
result = append(result, append([]int{}, path...))
}
if node.Left != nil {
queue = append(queue, node.Left)
sums = append(sums, sum+node.Left.Val)
newPath := append([]int{}, path...)
newPath = append(newPath, node.Left.Val)
paths = append(paths, newPath)
}
if node.Right != nil {
queue = append(queue, node.Right)
sums = append(sums, sum+node.Right.Val)
newPath := append([]int{}, path...)
newPath = append(newPath, node.Right.Val)
paths = append(paths, newPath)
}
}
return result
}