LeetCode 113. 路径总和 II
剑指 Offer 34. 二叉树中和为某一值的路径
给你二叉树的根节点
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]]示例 2:
输入:root = [1,2,3], targetSum = 5 输出:[]示例 3:
输入:root = [1,2], targetSum = 0 输出:[]提示:
- 树中节点总数在范围
[0, 5000]
内-1000 <= Node.val <= 1000
-1000 <= targetSum <= 1000
注意:本题与主站 113 题相同:力扣
思路:
参考 LeetCode题解(关于不理解 slice 导致的 bug)
时间复杂度:O(N),N 为二叉树的节点数,先序遍历需要遍历所有节点。
空间复杂度:O(N) , 最差情况下,即树退化为链表时,path
存储所有树节点,使用 O(N)O(N) 额外空间。
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
// 方式1 参考题解:https://leetcode.cn/problems/path-sum-ii/solutions/1075105/lc113-fengwei2002-guan-yu-bu-li-jie-slic-hank/
var res [][]int
func pathSum(root *TreeNode, targetSum int) [][]int {
res = make([][]int, 0)
subRes := make([]int, 0)
dfs(root, targetSum, subRes)
return res
}
func dfs(root *TreeNode, targetSum int, subRes []int) {
if root == nil {
return
}
targetSum -= root.Val
subRes = append(subRes, root.Val)
if root.Left == nil && root.Right == nil && targetSum == 0 {
// cp := make([]int, len(subRes))
// copy(cp, subRes)
// res = append(res, cp)
res = append(res, append([]int{}, subRes...))
return
}
dfs(root.Left, targetSum, subRes)
dfs(root.Right, targetSum, subRes)
// 回溯,避免影响其他层的递归结果
subRes = subRes[:len(subRes)-1] // pop
targetSum += root.Val
}
// func dfs(root *TreeNode, targetSum int, subRes []int) {
// if root == nil {
// return
// }
// subRes = append(subRes, root.Val)
// if root.Left == nil && root.Right == nil && targetSum == root.Val {
// // cp := make([]int, len(subRes))
// // copy(cp, subRes)
// // res = append(res, cp)
// res = append(res, append([]int{}, subRes...))
// return
// }
// dfs(root.Left, targetSum - root.Val, subRes)
// dfs(root.Right, targetSum - root.Val, subRes)
// // 回溯,避免影响其他层的递归结果
// subRes = subRes[:len(subRes)-1] // pop
// targetSum += root.Val
// }
// 方式2 闭包写法:
func pathSum(root *TreeNode, target int) [][]int {
res := make([][]int, 0)
nodes := make([]int, 0)
var dfs func(node *TreeNode, t int)
dfs = func(node *TreeNode, t int) {
if node == nil {
return
}
// @追加
nodes = append(nodes, node.Val)
// (1)路径和=target (2)根节点 -> 叶子节点
if t-node.Val == 0 && node.Left == nil && node.Right == nil {
// 为避免修改原nodes数组,所以新创建一个临时数组 []int{}
res = append(res, append([]int{}, nodes...))
}
dfs(node.Left, t-node.Val)
dfs(node.Right, t-node.Val)
// @回溯到添加元素前的状态,为了尝试另一种不同路线
// 注意:整条链路dfs()下探完后,再回溯走其他路线
nodes = nodes[:len(nodes)-1]
}
dfs(root, target)
return res
}
路径总和 系列题目: