思路:
先序遍历+递归
代码:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
if(A==null||B==null){
return false;
}
if(recur(A,B)){
return true;
}
return isSubStructure(A.left,B)||isSubStructure(A.right,B);
}
private boolean recur(TreeNode a,TreeNode b){
if(b==null){
return true;
}
if(a==null||a.val!=b.val){
return false;
}
return recur(a.left,b.left)&&recur(a.right,b.right);
}
}
分解:
1)分2步:
i)先在A先序遍历,寻找与B根节点值一致的节点
ii)调用另一个方法,查询A是否存在以该节点为根节点的B的子树
2)recur()终止条件:
i)B为空时,说明已匹配完成(true)
ii)A为空时,说明已经越过A的叶子节点也没有找到完整的B(false)
iii)A与B的值不同时(false)
3)主函数isSubStructure()的递归是:
isSubStructure(A.left,B)||isSubStructure(A.right,B)
因为B的根节点不会变,要搜寻A的左子树和右子树
recur()的递归是:
recur(A.left,B.left)&&recur(A.right,B.right)
因为此时已经认定找到了与B根节点一样的值,则根据这个节点A,A和B分别向左、右同时遍历
复杂度分析:
时间复杂度:O(MN) 先序遍历数A找根节点O(M),每次都调用recur()判断是否是子树(根节点+左右子树的判断)
空间复杂度:O(M) 最差的情况是A变为链表,遍历至叶子节点的深度为M,也就是每一层只有一个节点