力扣二叉树--第三十二天

前言

关于路径的两道题。掌握递归函数要不要返回值。用到了defer关键字,起到回溯的作用。

内容

一、路经总和

112.路径总和

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。

叶子节点 是指没有子节点的节点。

递归

确定递归函数的参数和返回类型

参数:需要二叉树的根节点,还需要一个计数器,这个计数器用来计算二叉树的一条边之和是否正好是目标和,计数器为int型。

再来看返回值,递归函数什么时候需要返回值?什么时候不需要返回值?这里总结如下三点:

  • 如果需要搜索整棵二叉树且不用处理递归返回值,递归函数就不要返回值。(这种情况就是本文下半部分介绍的113.路径总和ii)
  • 如果需要搜索整棵二叉树且需要处理递归返回值,递归函数就需要返回值。 (这种情况我们在236. 二叉树的最近公共祖先中介绍)
  • 如果要搜索其中一条符合条件的路径,那么递归一定需要返回值,因为遇到符合条件的路径了就要及时返回。(本题的情况)

确定终止条件

首先计数器如何统计这一条路径的和呢?

不要去累加然后判断是否等于目标和,那么代码比较麻烦,可以用递减,让计数器count初始为目标和,然后每次减去遍历路径节点上的数值。

如果最后count == 0,同时到了叶子节点的话,说明找到了目标和。

func hasPathSum(root *TreeNode, targetSum int) bool {
    if root==nil{
        return false
    }
targetSum-=root.Val
if root.Left==nil&&root.Right==nil&&targetSum==0{
    return true
}
 return hasPathSum(root.Left,targetSum)||hasPathSum(root.Right,targetSum)
}
二、路经总和II

113.路径总和II

给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

叶子节点 是指没有子节点的节点。

递归

要遍历整个树,找到所有路径,所以递归函数不要返回值!

func pathSum(root *TreeNode, targetSum int) [][]int {
    var result [][]int
    var vals []int
   var dfs func(node *TreeNode,sum int)
   dfs=func(node *TreeNode,sum int){
       if node==nil{
           return 
       }
       sum-=node.Val
       vals=append(vals,node.Val)
       defer func(){
           vals=vals[:len(vals)-1]
       }()//defer语句用于在每次递归调用结束后,将vals切片中最后添加的元素移除。即回溯到上一节点
if node.Left==nil&&node.Right==nil&&sum==0{
    result=append(result,append([]int(nil),vals...))
}//将 vals 切片中的所有元素追加到一个新的切片中
     if node.Left!=nil{
         dfs(node.Left,sum)
     }
     if node.Right!=nil{
         dfs(node.Right,sum)
     }
     
   }
   dfs(root,targetSum)
   return result
}

最后

今天先这样吧

你可能感兴趣的:(力扣二叉树,leetcode,算法,职场和发展,golang,二叉树)