从根节点到叶节点的路径中,找出所有节点值之和等于目标整数的路径

二元树路径求和问题的解决方案

问题分析
  • 目标:从根节点到叶节点的路径中,找出所有节点值之和等于目标整数的路径。
  • 关键约束:路径必须是从根到叶的完整路径(叶节点无左右子树)。
核心算法:深度优先搜索(DFS)
思路
  1. 递归遍历:从根节点出发,递归探索左右子树。
  2. 路径跟踪:用栈或列表记录当前路径的节点值。
  3. 和校验:到达叶节点时,检查路径和是否等于目标值,若相等则输出路径。
步骤示例(以目标和 22 为例):


路径 1:10 → 12
- 路径和:10 + 12 = 22 → 匹配目标,输出。
路径 2:10 → 5 → 7
- 路径和:10 + 5 + 7 = 22 → 匹配目标,输出。
实现要点
  1. 递归参数:当前节点、当前路径列表、当前路径和。
  2. 终止条件
    • 节点为空 → 直接返回。
    • 叶节点 → 校验路径和,匹配则打印路径。
  3. 回溯处理:递归返回后弹出当前节点(恢复路径状态,避免影响其他分支)。
代码实现(Python)

python


class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def find_path(root, target_sum):
result = []
def dfs(node, current_path, current_sum):
if not node:
return
# 更新路径和与当前路径
current_sum += node.val
current_path.append(node.val)
# 叶节点且和匹配
if not node.left and not node.right and current_sum == target_sum:
result.append(list(current_path)) # 深拷贝路径
# 递归左右子树
dfs(node.left, current_path, current_sum)
dfs(node.right, current_path, current_sum)
# 回溯:移除当前节点
current_path.pop()
dfs(root, [], 0)
return result
# 示例树构建
root = TreeNode(10)
root.left = TreeNode(5, TreeNode(4), TreeNode(7))
root.right = TreeNode(12)
# 测试:目标和 22
print(find_path(root, 22)) # 输出:[[10, 5, 7], [10, 12]]
复杂度分析
  • 时间复杂度:O(n),每个节点仅访问一次。
  • 空间复杂度:O(h),h 为树的高度(递归栈深度,最坏情况为链状树 O(n))。
扩展场景
  1. 路径不限制根到叶:需允许从任意节点开始/结束(需修改递归逻辑,取消叶节点限制)。
  2. 二叉搜索树(BST)优化:利用 BST 特性剪枝(如当前和超过目标时停止右子树搜索)。
  3. 记录路径坐标:扩展存储节点索引或指针,便于定位具体节点。

该方法通过深度优先搜索与回溯结合,高效遍历所有可能路径,是解决树路径求和问题的经典方案。

在二叉搜索树(BST)中进行路径求和剪枝时,可利用 左子树所有节点值 ≤ 当前节点值 ≤ 右子树所有节点值 的特性优化搜索。以下是具体实现:

核心剪枝逻辑

  1. 提前终止右子树搜索:若当前路径和 + 当前节点值 已超过目标值,则右子树所有路径和必然更大(因右子树节点值 ≥ 当前节点值),可直接剪枝。
  2. 保留左子树搜索:左子树节点值更小,可能存在和为目标值的路径,需继续递归。

代码实现(Python)

python


class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def find_bst_path(root, target_sum):
result = []
def dfs(node, current_path, current_sum):
if not node:
return
current_sum += node.val
current_path.append(node.val)
# 叶节点且和匹配:记录路径
if not node.left and not node.right and current_sum == target_sum:
result.append(list(current_path))
# 剪枝逻辑:仅当当前和 <= 目标值时,才搜索右子树
if current_sum <= target_sum:
dfs(node.right, current_path, current_sum) # 右子树可能存在更大值但和仍达标
# 左子树始终需要搜索(节点值更小,可能存在和为目标的路径)
dfs(node.left, current_path, current_sum)
# 回溯:移除当前节点
current_path.pop()
dfs(root, [], 0)
return result
# 示例 BST 构建(满足左 ≤ 中 ≤ 右)
root = TreeNode(10)
root.left = TreeNode(5, TreeNode(4), TreeNode(7)) # 左子树:5 (4,7)
root.right = TreeNode(12) # 右子树:12
# 测试:目标和 22
print(find_bst_path(root, 22)) # 输出:[[10, 5, 7], [10, 12]]

剪枝效果说明

  • 右子树剪枝:例如当前路径和为 10 + 12 = 22(已等于目标),此时右子树为空,无需处理;若目标和为 20,则 10 + 12 = 22 > 20,直接剪枝右子树,避免无效递归。
  • 左子树不剪枝:例如目标和为 19,当前路径 10 + 5 = 15 ≤ 19,需继续搜索左子树的 47(如 10 + 5 + 4 = 19 为有效路径)。

关键优化点

  • 剪枝条件current_sum <= target_sum 是右子树搜索的前提,利用 BST 右子树递增特性避免无效计算。
  • 与普通二叉树对比:普通二叉树需搜索所有路径(O(n)),而 BST 在目标值较小时可显著减少右子树遍历次数(最坏情况仍为 O(n),但平均效率提升)。

通过此剪枝策略,可在 BST 路径求和问题中有效减少不必要的递归,提升搜索效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Bol5261

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

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

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

打赏作者

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

抵扣说明:

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

余额充值