UNIT 01单树返回与修改
#104 二叉树的最大深度
- 子问题契约
- 一次调用返回以当前节点为根的最大深度。
- 分解与合并
- 读取左右子树深度,取较大者并计入当前节点。
- 返回与副作用
- 返回的是完整子树的摘要,不需要全局答案。
- 边界检查
- 空树深度为 0,叶子深度为 1;计数单位为节点。
迁移 · #111 二叉树的最小深度最小深度只允许沿真实存在的孩子到叶子,单空孩子不能取最小。
UNIT 02单树返回与修改
#226 翻转二叉树
- 子问题契约
- 一次调用返回当前子树的镜像根。
- 分解与合并
- 先得到原左右子树的镜像,再交换连接。
- 返回与副作用
- 修改发生在当前节点;返回根以便父节点重连。
- 边界检查
- 空节点原样返回,不丢失原左右子树入口。
迁移 · #101 对称二叉树对称树由修改单树变为比较两棵子树是否互为镜像。
UNIT 03双节点比较
#101 对称二叉树
- 子问题契约
- 一次双节点调用判断两棵子树是否互为镜像。
- 分解与合并
- 值相等后,交叉比较左与右、右与左。
- 返回与副作用
- 布尔结果覆盖两侧完整子树,两个递归条件都必须成立。
- 边界检查
- 双空成立,单空失败;形状和值都参与比较。
迁移 · #100 相同的树相同树保留基例和值检查,将交叉位置换成同向位置。
UNIT 04双节点比较
#100 相同的树
- 子问题契约
- 一次双节点调用判断两个对应子树是否完全相同。
- 分解与合并
- 值相等后,同向比较左右孩子。
- 返回与副作用
- 返回结构与数值同时一致的布尔结果。
- 边界检查
- 双空成立,单空失败,不能只比较遍历数值序列。
迁移 · #572 另一棵树的子树子树判断在大树中搜索起点,再复用相同树验证器。
UNIT 05搜索加验证
#572 另一棵树的子树
- 子问题契约
- 外层判断区域中是否存在目标子树,内层判断完整结构是否相同。
- 分解与合并
- 当前起点验证失败后,继续搜索左、右子树中的起点。
- 返回与副作用
- 外层使用存在关系,内层使用全部相同关系。
- 边界检查
- 候选节点值相等仍不代表整棵子树匹配。
迁移 · #1367 二叉树中的链表树中链表把内层验证改成向下路径匹配,外层搜索仍保留。
UNIT 06单支返回、双支更新
#543 二叉树的直径
- 子问题契约
- 返回从当前节点向下的最大单支深度。
- 分解与合并
- 当前节点左右深度相加,形成经过此节点的候选直径。
- 返回与副作用
- 向父返回一支;全局记录两支连接后的最大边数。
- 边界检查
- 返回深度按节点计,直径按边计,不能混淆单位。
迁移 · #124 二叉树中的最大路径和最大路径和把长度换成权值和,负增益分支可舍弃。
UNIT 07单支返回、双支更新
#124 二叉树中的最大路径和
- 子问题契约
- 返回父节点可以继续连接的最大单支增益。
- 分解与合并
- 用非负的左右增益更新经过当前节点的路径,再选择一侧返回。
- 返回与副作用
- 局部返回只能连一支,全局答案可连两支。
- 边界检查
- 答案初始化须覆盖全负数树,路径至少含一个节点。
迁移 · #687 最长同值路径同值路径把分支可用性改为父子值相同,仍区分单支和双支。
UNIT 08路径历史与恢复
#437 路径总和 III
- 子问题契约
- 当前根路径的前缀和,以及活动祖先前缀频次。
- 分解与合并
- 先查询需要的祖先前缀,再加入当前前缀,离开时撤销。
- 返回与副作用
- 每个孩子只看到自己的祖先历史,不包含兄弟分支。
- 边界检查
- 虚拟零前缀、重复前缀及负节点值都须保留正确计数。
迁移 · #560 和为 K 的子数组子数组和只有一条线性历史,不需要退出分支时的撤销。