参考大佬题解
这题需要遍历A的每一个节点a,判断B是否为a的子结构。因此可以分为两步来做
- 遍历A的每一个节点
node
函数isSubStructure
,这里采用先序遍历 - 判断B是否为
node
的子结构isSub
isSubStructure函数
- 递归参数:两个树节点
- 返回条件:A或者B为空时,直接返回false。因为A为空B不为空,那么B必然不是A的子结构;B为空,空树不是任何树的子结构
- 返回值:当满足以下三个条件之一,返回true。
- B是A的子结构
- B是A左子树的子结构
- B是A右子树的子结构
isSub函数
- 递归参数:两个树节点A和B
- 返回条件:B为空,说明已经判定完毕,返回true。A为空,说明判定失败,返回false。值得一提的是,应该优先判断B是否为空,否则遇到A,B同时为空时会被判定为false。
- 返回值:当同时满足以下三个条件之一,返回true。
- A的值和B的值相等
- A的左子树的值和B的左子树的值也相等
- A的右子树的值和B的右子树的值也相等
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
// A为空B不为空,那么B必然不是A的子结构
// B为空,空树不是任何树的子结构,返回false
if(A == null || B == null)
return false;
return isSub(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B);
}
private boolean isSub(TreeNode A, TreeNode B){
if(B == null)
return true;
if(A == null)
return false;
return A.val == B.val && isSub(A.left, B.left) && isSub(A.right, B.right);
}
}
算法复杂度
- 时间复杂度: O ( m n ) O(mn) O(mn), m m m和 n n n表示A和B的节点数量,遍历A的每个节点需要 O ( m ) O(m) O(m),而A的每个节点又要调用isSub函数,用时 O ( n ) O(n) O(n)
- 空间复杂度: O ( m ) O(m) O(m),当A和B同时退化成链表,占用空间最大。那么递归深度不会超过遍历A的深度。