第5章|二叉树与递归
Unit 05 · LeetCode #572 另一棵树的子树
先搜索候选起点,
再验证完整子树。
根值相同只是“值得尝试”的信号。本题真正训练的是两个递归契约如何协作:外层搜索回答“哪里可能存在”,内层验证回答“当前候选是否严格相同”。
same_tree(a,b) 从两个确定根出发,严格验证空结构、节点值和左右子树。
isSubtree(root,subRoot) 枚举候选起点;每次尝试仍交给 Unit 04 的验证器。
题目要求
给定二叉树 root 和 subRoot,判断 root 中是否存在一棵子树,其结构和节点值与 subRoot 完全相同。子树必须包含候选根的全部后代。
root节点数:1–2000subRoot节点数:1–1000- 节点值范围:−10⁴–10⁴
示例
subRoot = [4,1,2]
输出:true
subRoot = [4,1,2]
输出:false
朴素递归在主树每个节点上尝试一次相同树验证,最坏时间复杂度 O(nm),递归栈约为 O(h₁+h₂)。
根值与目标根相同的位置。它只触发验证,不直接产生答案。
当前搜索区域中是否存在一个完整匹配的起点。
两个已经确定的根所代表的完整子树是否相同。
验证成功后停止搜索;当前候选失败后继续搜索其他区域。
目标树 subRoot = [4,1,2]
当前根、左区域、右区域三选一成功即可。
空结构、值、左右子树必须全部通过。
候选根记录
当前调用栈
搜索器不变量
search(node) 判断以 node 为根的整个区域中是否存在目标子树。
验证器不变量
same_tree(a,b) 判断两个确定根所代表的完整子树是否完全相同。
迁移目标:LeetCode #1367 二叉树中的链表
继续复用“外层搜索起点+内层验证关系”的双函数结构。唯一关键变化:内层不再验证完整子树,而是让链表剩余部分沿树的一条向下路径匹配。
LeetCode #1367|Linked List in Binary Tree
迁移原题
给定链表头节点 head 和二叉树根节点 root,判断树中是否存在一条从某个节点开始、持续向下的路径,其节点值序列与链表完全一致。
示例与关键差异
树中路径:4 → 2 → 0
输出:true
路径匹配成功后,不要求当前树节点的另一条分支也与链表对应;只需下一项能在左或右孩子中继续。
复用的是“双层职责”,不是 same_tree 的全部条件
在主树每个节点上尝试当前关系,失败后继续左、右区域。
仍在树中枚举链表路径的候选起点。
当前候选根值与 head.val 不相等时,能否全局返回 False?
内层关系从“完整相同”变成“单路径延伸”
左右两侧都必须匹配,使用 left AND right。
链表下一项进入左或右任一孩子即可,使用 left OR right。
节点 2 的左孩子匹配到 0 后,是否还要求右孩子也匹配链表下一项?
拼接外层搜索与内层路径匹配
or:外层枚举起点,内层选择下一条边。运行 [4,2,0]:外层找到 B,内层只沿 B → E → F
请停留几秒,重新观察刚刚改变的树状态与调用边界。