题目描述
其他相同题型可以参照🔗
解题思路
recur(A, B) 函数:
终止条件:
- 当节点 B 为空:说明树 B 已匹配完成(越过叶子节点),因此返回 true ;
- 当节点 A 为空:说明已经越过树 A 的叶节点,即匹配失败,返回 false ;
- 当节点 A 和 B 的值不同:说明匹配失败,返回 false ;
返回值:
- 判断 A 和 B 的 左子节点 是否相等,即 recur(A.left, B.left) ;
- 判断 A 和 B 的 右子节点 是否相等,即 recur(A.right, B.right) ;
isSubStructure(A, B) 函数:
- 特例处理: 当 树 A 为空 或 树 B 为空 时,直接返回 false ;
- 返回值: 若树 B 是树 A 的子结构,则必满足以下三种情况之一,因此用或 || 连接;
- 以 节点 A 为根节点的子树 包含树 B ,对应 recur(A, B);
- 树 B 是 树 A 左子树 的子结构,对应 isSubStructure(A.left, B);
- 树 B 是 树 A 右子树 的子结构,对应 isSubStructure(A.right, B);
此题需要判断的是子树,而不是从根节点开始,所以相当于需要深度遍历数A,再从树A的每个节点进行比较判断.
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
return (A !=null && B != null) && (recur(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B));
}
public boolean recur(TreeNode A, TreeNode B) {
if (B == null) return true;
else if (A == null || A.val != B.val) return false;
else return recur(A.left, B.left) && recur(A.right, B.right);
}
}
- 时间复杂度 O(MN) : 其中 M,N 分别为树 A 和 树 B 的节点数量;先序遍历树 A 占用 O(M) ,每次调用 recur(A, B) 判断占用 O(N) 。
- 空间复杂度 O(M) : 当树 A 和树 B 都退化为链表时,递归调用深度最大。当 M≤N 时,遍历树 A 与递归判断的总递归深度为 M ;当 M>N 时,最差情况为遍历至树 A 的叶节点,此时总递归深度为 M。