572. 另一棵树的子树 
题目描述
给定二叉树 root 和 subRoot,判断 root 中是否存在一棵与 subRoot 结构和值完全相同的子树。
这里的“子树”不是任意截取一段结构,而是必须以 root 中某个节点为根,并包含这个节点下面的所有后代。
题型判断
问题分为两层:
- 在
root中枚举可能的子树根节点。 - 判断从两个根节点开始的树是否完全相同。
两层都天然适合递归 DFS。只找到相同根值不够,还必须比较完整结构。
核心思路
isSameTree(first, second)同步比较两棵树。isSubtree(root, subRoot)判断当前位置是否相同;若不同,再去左右子树寻找。
isSameTree(first, second) 判断两棵树是否完全相同:
- 两个节点都为空,说明这一侧都没有节点,返回
true。 - 只有一个节点为空,说明结构不同,返回
false。 - 两个节点值不同,返回
false。 - 当前节点相同后,继续比较左子树和右子树。
isSubtree(root, subRoot) 负责枚举 root 中的每个节点:
- 先判断以当前
root为根的树,是否和subRoot完全相同。 - 如果不同,再去
root.left中继续找。 - 如果左子树也没有,再去
root.right中继续找。
执行过程示例
以 root = [3,4,5,1,2]、subRoot = [4,1,2] 为例:
代码实现
复杂度分析
设 root 有 n 个节点,subRoot 有 m 个节点:
- 时间复杂度:最坏
O(n × m),每个候选节点都可能比较m个节点。 - 空间复杂度:
O(h1 + h2),来自枚举和比较时的递归栈。最坏情况下两棵树都退化成链表,空间复杂度为O(n + m);平衡二叉树中约为O(log n + log m)。
边界与易错点
- LeetCode 约束中
subRoot非空;若业务定义允许空树,通常应约定空树是任意树的子树。 - 当
root为空而subRoot非空时,返回false。 - 子树必须从某个节点开始,并包含这个节点的所有后代,不能只匹配中间一部分结构。
- 不能只比较先序遍历的节点值,必须保留空节点标记才能区分结构。
- 数据量更大时,可以序列化后做字符串匹配,或使用树哈希降低重复比较成本。

