路径总和III

简介: 路径总和III

公众号merlinsea


  • 给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。
  • 路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。、

640.png

  • 解题思路
  • 先序遍历的变种,从根节点出发,每个节点可以选也可以不选,但需要保证连续性。
  • 在遍历的过程中有一个列表维护到达当前节点的可能的结果有哪些,默认初始化列表中只有[0],遍历了根节点以后列表得到[0,5],继续向下遍历左子树,得到列表的结果是[0,4,9],其中0表示什么节点都没有选择,4代表只选择了4号节点,9表示选择了4号节点和5号节点,因此保证了连续性。
  • 在这里如果所有节点共用一个列表,则在遍历的过程中需要考虑回溯问题,但如果每递归访问一个节点都是可以确保是新的拷贝后的列表,则不需要考虑回溯问题。


640.png


  • 代码实现
  • 节点的定义


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专题刷题来啦!!!!

鱼皮编程导航的优惠券,扫码即可领取

公众号:梁霖编程工具库
今天我加入鱼皮知识新球了!!


相关文章
|
5月前
leetcode113路径总和2
leetcode113路径总和2
52 0
|
5月前
|
C++
路径总和(C++)
路径总和(C++)
34 1
|
5月前
|
算法 前端开发
前端算法-路径总和
前端算法-路径总和
|
5月前
leetcode-437:路径总和 III
leetcode-437:路径总和 III
43 0
|
5月前
|
Java C++ Python
leetcode-112:路径总和
leetcode-112:路径总和
43 0
|
5月前
|
存储 算法 程序员
【算法训练-二叉树 六】【路径和计算】路径总和I、路径总和II、路径总和III、二叉树的最大路径和
【算法训练-二叉树 六】【路径和计算】路径总和I、路径总和II、路径总和III、二叉树的最大路径和
70 0
LeetCode 437. 路径总和 III
LeetCode 437. 路径总和 III
77 0
LeetCode 437. 路径总和 III
112. 路径总和
112. 路径总和
58 0
112. 路径总和