第5章|二叉树与递归

Unit 05 · LeetCode #572 另一棵树的子树

← Unit 04
仅本次页面有效
U05
Subtree of Another TreeSearch · Verify · Short-circuit

先搜索候选起点,
再验证完整子树。

根值相同只是“值得尝试”的信号。本题真正训练的是两个递归契约如何协作:外层搜索回答“哪里可能存在”,内层验证回答“当前候选是否严格相同”。

已恢复上次学习位置阶段、候选状态、运行轨迹、代码与编辑器高度均已恢复。
知识桥梁|Unit 04 → Unit 05
Unit 04:验证器

same_tree(a,b) 从两个确定根出发,严格验证空结构、节点值和左右子树。

增加一个外层搜索 →
Unit 05:搜索器+验证器

isSubtree(root,subRoot) 枚举候选起点;每次尝试仍交给 Unit 04 的验证器。

贯穿本单元的审查问题当前函数是在“寻找可能的位置”,还是在“证明当前位置严格成立”?
LeetCode #572 原题题意、示例与复杂度

题目要求

给定二叉树 root 和 subRoot,判断 root 中是否存在一棵子树,其结构和节点值与 subRoot 完全相同。子树必须包含候选根的全部后代。

class Solution: def isSubtree( self, root: Optional[TreeNode], subRoot: Optional[TreeNode] ) -> bool: pass
  • root 节点数:1–2000
  • subRoot 节点数:1–1000
  • 节点值范围:−10⁴–10⁴

示例

root = [3,4,5,1,2]
subRoot = [4,1,2]
输出:true
root = [3,4,5,1,2,null,null,null,null,0]
subRoot = [4,1,2]
输出:false

朴素递归在主树每个节点上尝试一次相同树验证,最坏时间复杂度 O(nm),递归栈约为 O(h₁+h₂)。

候选根

根值与目标根相同的位置。它只触发验证,不直接产生答案。

搜索契约

当前搜索区域中是否存在一个完整匹配的起点。

验证契约

两个已经确定的根所代表的完整子树是否相同。

短路

验证成功后停止搜索;当前候选失败后继续搜索其他区域。

教学主树黄色节点是根值相同的候选起点
黄色:候选根橙色:当前函数绿色:验证通过红色:首个失败位置

目标树 subRoot = [4,1,2]

外层 search当前区域是否存在目标?

当前根、左区域、右区域三选一成功即可。

内层 same_tree当前两棵完整子树是否相同?

空结构、值、左右子树必须全部通过。

候选根记录

当前调用栈

尚未进入运行轨迹
当前 root3 (A)
当前函数search
验证结果—
全局结果—

搜索器不变量

search(node) 判断以 node 为根的整个区域中是否存在目标子树。

验证器不变量

same_tree(a,b) 判断两个确定根所代表的完整子树是否完全相同。

已访问主树节点0 / 9
已尝试候选0 / 2
当前函数search
调用栈深度0
最终结果—
搜索器与验证器的交接轨迹1 / 11

当前运行状态动画只展示控制权变化
当前 root—
当前函数—
same_tree 返回—
search 下一步—
候选 B未验证
候选 G未验证
七个语义槽位只拼接两个函数之间的职责边界
实时组装结果观察 search 使用 or,verify 使用 and

迁移目标:LeetCode #1367 二叉树中的链表

继续复用“外层搜索起点+内层验证关系”的双函数结构。唯一关键变化:内层不再验证完整子树,而是让链表剩余部分沿树的一条向下路径匹配。

LeetCode #1367|Linked List in Binary Tree

标签:链表 · 二叉树 · DFS
中等

迁移原题

给定链表头节点 head 和二叉树根节点 root,判断树中是否存在一条从某个节点开始、持续向下的路径,其节点值序列与链表完全一致。

class Solution: def isSubPath( self, head: Optional[ListNode], root: Optional[TreeNode] ) -> bool: pass

打开 LeetCode 原题 ↗

示例与关键差异

链表:[4,2,0]
树中路径:4 → 2 → 0
输出:true

路径匹配成功后,不要求当前树节点的另一条分支也与链表对应;只需下一项能在左或右孩子中继续。

复用的是“双层职责”,不是 same_tree 的全部条件

#572 外层搜索

在主树每个节点上尝试当前关系,失败后继续左、右区域。

保留 →
#1367 外层搜索

仍在树中枚举链表路径的候选起点。

当前候选根值与 head.val 不相等时,能否全局返回 False?

内层关系从“完整相同”变成“单路径延伸”

#572:完整子树

左右两侧都必须匹配,使用 left AND right。

#1367:一条向下路径

链表下一项进入左或右任一孩子即可,使用 left OR right。

4→2→0在教学树中沿 B → E → F 匹配

节点 2 的左孩子匹配到 0 后,是否还要求右孩子也匹配链表下一项?

拼接外层搜索与内层路径匹配

运行 [4,2,0]:外层找到 B,内层只沿 B → E → F

head4
tree3 (A)
当前函数isSubPath
选择的边—
参考答案只在完成脚手架后查看更有价值

本环节已完成

请停留几秒,重新观察刚刚改变的树状态与调用边界。

环节 1 / 6