112. 路径总和

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

说明: 叶子节点是指没有子节点的节点。

示例: 给定如下二叉树,以及目标和 sum = 22,

返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。

思路:

只要找到一条符合条件的路径,就立刻返回,没必要遍历所有节点。

往下遍历,每遍历到一个节点,就减掉这个节点的值。如果这条路径遍历到叶子结点,所剩的值还不是0,那就说明这条路径不对,回溯,每回溯一个节点就加上对应的值,再去遍历其他路径。

代码:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def traversal(self, cur: TreeNode, count: int) -> bool:
        if not cur.left and not cur.right and count == 0: # 遇到叶子节点,并且计数为0
            return True
        if not cur.left and not cur.right: # 遇到叶子节点直接返回
            return False
        
        if cur.left: # 左
            count -= cur.left.val
            if self.traversal(cur.left, count): # 递归,处理节点
                return True
            count += cur.left.val # 回溯,撤销处理结果
            
        if cur.right: # 右
            count -= cur.right.val
            if self.traversal(cur.right, count): # 递归,处理节点
                return True
            count += cur.right.val # 回溯,撤销处理结果
            
        return False
    
    def hasPathSum(self, root: TreeNode, sum: int) -> bool:
        if root is None:
            return False
        return self.traversal(root, sum - root.val)  

逐步讲解:

1. 定义二叉树节点类

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

这是一个二叉树节点类的定义。每个节点有一个值(val),以及指向其左子节点(left)和右子节点(right)的指针。

2. 解决方案类

class Solution:
    def traversal(self, cur: TreeNode, count: int) -> bool:
        if not cur.left and not cur.right and count == 0: # 遇到叶子节点,并且计数为0
            return True
        if not cur.left and not cur.right: # 遇到叶子节点直接返回
            return False

这是一个递归函数,用于遍历二叉树并检查是否存在从根节点到叶子节点的路径,使路径上所有节点值的和等于给定的sum

  • cur 是当前节点。
  • count 是当前路径上剩余的需要达到的目标和。

如果当前节点是叶子节点,并且 count 等于 0,那么返回 True,表示找到了目标路径。 如果当前节点是叶子节点,但 count 不等于 0,返回 False,表示这条路径不满足条件。

3. 处理左子节点

        if cur.left: # 左
            count -= cur.left.val
            if self.traversal(cur.left, count): # 递归,处理节点
                return True
            count += cur.left.val # 回溯,撤销处理结果
  • 如果当前节点有左子节点,则减去左子节点的值。
  • 递归地处理左子节点,如果找到满足条件的路径,返回 True
  • 如果递归处理后没有找到满足条件的路径,回溯并撤销减去左子节点值的操作。

4. 处理右子节点

        if cur.right: # 右
            count -= cur.right.val
            if self.traversal(cur.right, count): # 递归,处理节点
                return True
            count += cur.right.val # 回溯,撤销处理结果
            
        return False
  • 如果当前节点有右子节点,则减去右子节点的值。
  • 递归地处理右子节点,如果找到满足条件的路径,返回 True
  • 如果递归处理后没有找到满足条件的路径,回溯并撤销减去右子节点值的操作。

5. 主函数

    def hasPathSum(self, root: TreeNode, sum: int) -> bool:
        if root is None:
            return False
        return self.traversal(root, sum - root.val)  

这是主函数,用于判断给定的二叉树是否存在路径,使路径上所有节点值的和等于给定的 sum

  • 如果根节点为空,返回 False,表示没有路径。
  • 调用 traversal 函数,从根节点开始递归查找路径,同时将 sum 减去根节点的值。

综上所述,这段代码通过深度优先搜索(DFS)递归地遍历二叉树,检查是否存在路径使路径上所有节点值的和等于给定的 sum。在遍历过程中,通过回溯机制来撤销之前的操作,确保不会漏掉任何可能的路径。

  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值