LeetCode【0112】路径总和

1 中文题目

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

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

示例:
在这里插入图片描述

输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出:True
解释:等于目标和的根节点到叶节点路径如上图所示。

在这里插入图片描述

输入:root = [1,2,3], targetSum = 5
输出:False
解释:树中存在两条根节点到叶子节点的路径:
(1 --> 2): 和为 3
(1 --> 3): 和为 4
不存在 sum = 5 的根节点到叶子节点的路径。
输入:root = [], targetSum = 0
输出:False
解释:由于树是空的,所以不存在根节点到叶子节点的路径。

提示:

  • 树中节点的数目在范围 [ 0 , 5000 ] [0, 5000] [0,5000]
  • − 1000 ≤ N o d e . v a l ≤ 1000 -1000 \leq Node.val \leq 1000 1000Node.val1000
  • − 1000 ≤ t a r g e t S u m ≤ 1000 -1000 \leq targetSum \leq 1000 1000targetSum1000

2 求解方法:递归

2.1 方法思路

方法核心

使用递归的方式,每访问一个节点就从目标和中减去当前节点的值,当到达叶子节点时,如果剩余值正好等于叶子节点的值则找到了一条满足条件的路径,通过或运算组合左右子树的结果,只要存在一条满足条件的路径即可返回True,这种方法通过自顶向下的递归和及时返回机制实现了最优的时空复杂度。

实现步骤

  • 基本情况处理
    • 检查输入树是否为空,空树直接返回False
    • 检查当前节点是否为叶子节点
    • 叶子节点时比较节点值和目标和是否相等
  • 递归过程设计
    • 从目标和中减去当前节点的值得到新的目标和
    • 对左子树进行递归,目标和为更新后的值
    • 对右子树进行递归,目标和为更新后的值
    • 使用或运算组合左右子树的结果
  • 路径记录方式
    • 通过减法隐式记录路径和
    • 不需要额外空间存储路径信息
    • 递归过程自动维护路径状态
  • 提前返回机制
    • 空节点直接返回False
    • 叶子节点直接判断并返回
    • 任一子树返回True则整体返回True
  • 路径定义处理
    • 必须从根节点开始
    • 必须到叶子节点结束
    • 节点值可以为负数
    • 路径不能半途而废

方法示例

root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22 为例:

5
      / \
     4   8
    /   / \
   11  13  4
  /  \      \
 7    2      1

执行过程:
1. 根节点5
   - 不是叶子节点
   - 更新目标和:22 - 5 = 17
   - 递归检查左右子树

2. 节点4(左子树)
   - 不是叶子节点
   - 更新目标和:17 - 4 = 13
   - 递归检查左子树

3. 节点11
   - 不是叶子节点
   - 更新目标和:13 - 11 = 2
   - 递归检查左右子树

4. 节点7(左)
   - 是叶子节点
   - 比较:7 != 2
   - 返回False

5. 节点2(右)
   - 是叶子节点
   - 比较:2 == 2
   - 返回True

6. 发现满足条件的路径:5->4->11->2,和为22
   最终返回True

2.2 Python代码

class Solution:
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        # 处理空树的情况
        if not root:
            return False
            
        # 如果当前是叶子节点,检查路径和是否等于目标值
        if not root.left and not root.right:
            return root.val == targetSum
            
        # 更新目标值(减去当前节点的值)
        remain = targetSum - root.val
        
        # 递归检查左右子树是否存在满足条件的路径
        # 只要有一条路径满足即可返回True
        return (self.hasPathSum(root.left, remain) or 
                self.hasPathSum(root.right, remain))

2.3 复杂度分析

  • 时间复杂度:O(N),N为树中节点总数
    • 最坏情况需要访问所有节点
    • 每个节点最多访问一次
  • 空间复杂度:O(H),H为树的高度
    • 递归调用栈的最大深度
    • 平衡树时为O(logN)
    • 最坏情况(单链树)为O(N)
    • 没有使用额外存储空间

3 题目总结

题目难度:简单
数据结构:二叉树
应用算法:递归

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AnFany

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值