公众号merlinsea
- 给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。
- 路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。、
- 解题思路
- 先序遍历的变种,从根节点出发,每个节点可以选也可以不选,但需要保证连续性。
- 在遍历的过程中有一个列表维护到达当前节点的可能的结果有哪些,默认初始化列表中只有[0],遍历了根节点以后列表得到[0,5],继续向下遍历左子树,得到列表的结果是[0,4,9],其中0表示什么节点都没有选择,4代表只选择了4号节点,9表示选择了4号节点和5号节点,因此保证了连续性。
- 在这里如果所有节点共用一个列表,则在遍历的过程中需要考虑回溯问题,但如果每递归访问一个节点都是可以确保是新的拷贝后的列表,则不需要考虑回溯问题。
- 代码实现
- 节点的定义
type TreeNode struct { Val int Left *TreeNode Right *TreeNode }
- 算法实现
package main // 路径总和III import ( "awesomeProject/leetcode01" "fmt" "strconv" ) var res int = 0 func main() { valSlice := []string{"5", "4", "8", "11", "", "13", "4", "7", "2", "", "", "5", "1"} root := createTree(valSlice) pathSum(root, 22) fmt.Println("res ", res) } func pathSum(root *leetcode01.TreeNode, targetSum int) { preList := make([]int, 0) preList = append(preList, 0) preOrder(root, targetSum, &preList) //preOrderTest(root, targetSum, preList) } // 由于传入的是地址指针,因此共用一个slice,需要回溯结果 func preOrder(root *leetcode01.TreeNode, targetSum int, preListPtr *[]int) { if root == nil { return } for i := 0; i < len(*preListPtr); i++ { (*preListPtr)[i] = (*preListPtr)[i] + root.Val if (*preListPtr)[i] == targetSum { res++ } } *preListPtr = append(*preListPtr, 0) fmt.Printf("%p\n", preListPtr) preOrder(root.Left, targetSum, preListPtr) preOrder(root.Right, targetSum, preListPtr) // 回溯 *preListPtr = (*preListPtr)[:len(*preListPtr)-1] for i := 0; i < len(*preListPtr); i++ { (*preListPtr)[i] = (*preListPtr)[i] - root.Val } } // 切片通过append以后返回的是一个新的地址,因此不需要回溯 func preOrderTest(root *leetcode01.TreeNode, targetSum int, preList []int) { if root == nil { return } // 这里返回的是一个新的list preList = append(preList, 0) //fmt.Printf("%p\n", &preList) for i := 0; i < len(preList)-1; i++ { preList[i] = preList[i] + root.Val if preList[i] == targetSum { res++ } } preOrderTest(root.Left, targetSum, preList) preOrderTest(root.Right, targetSum, preList) } // 构造树 func createTree(valSlice []string) *leetcode01.TreeNode { val, _ := strconv.Atoi(valSlice[0]) root := &leetcode01.TreeNode{ Val: val, Left: nil, Right: nil, } var queue = make([]*leetcode01.TreeNode, 0) queue = append(queue, root) var i = 1 for len(queue) != 0 && i < len(valSlice) { p := queue[0] queue = queue[1:] // 构造左子树 if valSlice[i] != "" { val, _ = strconv.Atoi(valSlice[i]) left := &leetcode01.TreeNode{ Val: val, Left: nil, Right: nil, } p.Left = left queue = append(queue, left) } i++ // 构造右子树 if i < len(valSlice) && valSlice[i] != "" { val, _ = strconv.Atoi(valSlice[i]) right := &leetcode01.TreeNode{ Val: val, Left: nil, Right: nil, } p.Right = right queue = append(queue, right) } i++ } return root }
golang版本永久算法题训练营~~
奔跑的小梁,公众号:梁霖编程工具库
算法训练营golang专题刷题来啦!!!!鱼皮编程导航的优惠券,扫码即可领取
公众号:梁霖编程工具库
今天我加入鱼皮知识新球了!!