在实现当中主要分为两个函数:
isSubStructure
:的主要作用是从当前两个根结点开始判断Tree2
是否是Tree1
的子结构,传入参数为Tree1
中的任意一个非空结点和Tree2
的根结点。作用就是将Tree1
拆分成若干个子树与Tree2
进行逐个对比。
DoesTree1HaveTree2
:一旦找到两个相同值的结点,就可以接着往下进行对比了。这里就要调用DoesTree1HaveTree2
,它的作用就是帮助判断值相同的根结点所形成的两个子树是否具有相同结构。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
bool res=false;
if(A && B){
if(A->val==B->val) res = DoesTree1HaveTree2(A,B);
if(!res)
res = isSubStructure(A->left,B);
if(!res)
res = isSubStructure(A->right,B);
}
return res;
}
bool DoesTree1HaveTree2(TreeNode* pRoot1,TreeNode* pRoot2){
if(!pRoot2) return true;
if(!pRoot1) return false;
if(pRoot1->val != pRoot2->val) return false;
return DoesTree1HaveTree2(pRoot1->left,pRoot2->left) &&
DoesTree1HaveTree2(pRoot1->right,pRoot2->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
。