news 2026/10/27 7:34:53

UVa 112二叉树路径求和问题解析与实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UVa 112二叉树路径求和问题解析与实现

1. UVa 112 Tree Summing 问题解析

这道来自UVa Online Judge的经典二叉树题目,困扰了无数算法初学者。我第一次遇到它时,花了整整三天才彻底理解题目描述和边界条件。让我们从实际问题出发,逐步拆解这个看似简单却暗藏玄机的二叉树路径求和问题。

2. 题目核心需求分析

2.1 输入格式的特殊性

题目输入采用LISP风格的括号嵌套表示法,例如:

(5(4(11(7()())(2()())))(8(13()())(4()(1()()))))

表示的是这样一棵二叉树:

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

这种表示法的特点是:

  • 每个非空节点表示为 (值 左子树 右子树)
  • 空子树用 () 表示
  • 节点值可能为负数(这是第一个坑点)

2.2 问题本质理解

我们需要判断:是否存在从根节点到叶子节点的路径,使得路径上所有节点值之和等于给定的目标数。注意几个关键约束:

  1. 空树情况需要特殊处理(即使目标sum=0也应返回false)
  2. 路径必须终止于叶子节点(即左右子树均为空的节点)
  3. 节点值可能是负数(影响剪枝策略)

3. 算法设计与实现

3.1 递归解析方案

最直观的解法是递归构建二叉树+DFS遍历。核心步骤:

class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def build_tree(s): # 解析字符串构建二叉树 pass def has_path_sum(root, target): if not root: return False if not root.left and not root.right: return target == root.val return has_path_sum(root.left, target - root.val) or \ has_path_sum(root.right, target - root.val)

3.2 输入处理的魔鬼细节

实际处理输入时有几个易错点:

  1. 输入可能跨多行(需要用while循环读取直到遇到特定括号数)
  2. 节点值可能为多位数或负数(正则表达式应匹配"-?\d+")
  3. 空树表示为(),此时无论target为何值都应返回false

建议的输入处理代码结构:

import re from collections import deque def parse_input(): s = "" left_paren = 0 while True: line = input().strip() s += line left_paren += line.count('(') - line.count(')') if left_paren == 0 and s: break return s

4. 优化与边界处理

4.1 提前终止优化

当发现某条路径已经不可能满足条件时(如当前和远超目标值且后续全为正数),可以提前终止该分支的搜索。但在节点值可能为负数的情况下,这种优化需要谨慎。

4.2 特殊测试用例

必须考虑的边界情况:

  1. 空树:输入"()",任何target都应返回no
  2. 单节点树:如"(5()())",target=5返回yes
  3. 负值路径:如"(-1(-2()())())",target=-3返回yes
  4. 多位数节点:如"(123()())",target=123返回yes

5. 完整参考实现

import sys import re def main(): for line in sys.stdin: line = line.strip() if not line: continue # 提取目标值 target = int(line) # 读取树结构 tree_str = "" left_paren = 0 while True: line = sys.stdin.readline() if not line: break tree_str += line.strip() left_paren += line.count('(') - line.count(')') if left_paren == 0: break # 处理空树 if tree_str == "()": print("no") continue # 构建树 stack = [] root = None i = 0 while i < len(tree_str): if tree_str[i] == '(': i += 1 # 提取节点值 match = re.match(r'-?\d+', tree_str[i:]) if match: val = int(match.group()) node = TreeNode(val) if stack: parent = stack[-1] if not parent.left: parent.left = node else: parent.right = node else: root = node stack.append(node) i += len(match.group()) elif tree_str[i] == ')': if stack: stack.pop() i += 1 else: i += 1 # DFS检查路径和 def dfs(node, current_sum): if not node: return False current_sum += node.val if not node.left and not node.right: return current_sum == target return dfs(node.left, current_sum) or dfs(node.right, current_sum) print("yes" if dfs(root, 0) else "no") if __name__ == "__main__": main()

6. 调试技巧与常见错误

6.1 典型WA原因

  1. 未处理多行输入:UVa的测试用例经常一个树的表示跨越多行
  2. 空树判断错误:看到"()"直接返回而忽略了后续测试用例
  3. 负号处理遗漏:正则表达式忘记考虑负值情况
  4. 多位数解析错误:只读取单个数字字符导致数值错误

6.2 调试建议

  1. 先编写树可视化函数辅助调试:
def print_tree(node, indent=""): if not node: print(indent + "None") return print(indent + str(node.val)) print_tree(node.left, indent + " ") print_tree(node.right, indent + " ")
  1. 使用以下测试用例验证:
22 (5(4(11(7()())(2()())))(8(13()())(4()(1()())))) 0 () 10 (5()(5()(5()(5()(5()())))))
  1. 在UVa讨论区查找特殊测试用例,许多用户会分享导致WA的边界案例

7. 算法复杂度分析

设树有n个节点:

  • 构建树:O(n) 每个节点处理一次
  • DFS遍历:O(n) 每个节点访问一次
  • 空间复杂度:O(h) 递归栈深度,最坏情况O(n)

对于UVa的判题限制(通常n≤10000),这个复杂度完全足够。如果遇到更大数据量,可以考虑迭代式DFS来避免栈溢出。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/27 7:33:27

HTML转EXE实战:Electron打包配置与避坑

简介&#xff1a;这份HTML转EXE工具包面向希望把HTML页面、CSS样式、JavaScript脚本及图片等前端资源封装成Windows可执行程序的开发者&#xff0c;适合需要离线分发Web内容、制作独立桌面应用或进行内部演示的场景。压缩包共3个文件&#xff0c;含1个exe主程序、1个htm说明页面…

作者头像 李华
网站建设 2026/10/27 7:32:35

跨平台AI Agent开发:挑战、架构与优化策略

1. 跨平台Agent Skills开发的核心挑战与机遇在2023年AI技术爆发式增长的背景下&#xff0c;Agent开发已成为最炙手可热的技术方向之一。作为一名经历过三次技术浪潮的老兵&#xff0c;我亲眼见证了从单一模型调用到复杂Agent系统的演进过程。当前开发者面临的最大痛点&#xff…

作者头像 李华
网站建设 2026/10/27 7:32:18

帧间预测十一种方法解析:运动模型、正则项与凸优化避坑

简介&#xff1a;这份凸优化大作业代码包面向学习运动估计与计算机视觉课程的学生&#xff0c;围绕MV子视角的帧间预测任务&#xff0c;给出十一种可运行的实现思路&#xff1a;运动估计部分包含穷尽块匹配、三步搜索与分层块匹配&#xff0c;另设光流估计和单应性矩阵两类方法…

作者头像 李华
网站建设 2026/10/27 7:32:16

marketingskills:从发帖技巧到真实用户连接的能力重建

1. 这不是“学营销”&#xff0c;而是重建你和真实用户之间的连接能力“marketingskills”这个词最近在招聘平台、自由职业接单群、甚至小红书知识博主的标题里高频出现&#xff0c;但它绝不是指背熟4P理论或能画出AARRR漏斗图就完事了。我带过37个从零起步转行做私域运营的学员…

作者头像 李华
网站建设 2026/10/27 7:30:09

品牌战略地图:6格模型解决企业品牌建设痛点

1. 品牌战略地图的价值与核心逻辑第一次接触品牌战略地图这个概念时&#xff0c;我正面临一个典型的企业困境&#xff1a;市场部天天喊"提升品牌价值"&#xff0c;销售部执着于"本月KPI"&#xff0c;产品团队则埋头优化功能。各部门都在努力&#xff0c;但…

作者头像 李华
网站建设 2026/10/27 7:29:47

基于YOLOv3与OpenCV的智慧交通车流量统计系统

1. 项目概述&#xff1a;当计算机视觉遇上智慧交通去年帮学弟调试这个车流量统计系统时&#xff0c;我们在校门口实测的场景至今记忆犹新——下午五点的放学高峰&#xff0c;系统准确捕捉到了每分钟87辆车的峰值流量&#xff0c;与交管部门的手动计数误差不超过3%。这正是基于O…

作者头像 李华