给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。
二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。
示例 1:
输入:root = [3,4,5,1,2], subRoot = [4,1,2] 输出:true
示例 2:
输入:root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2] 输出:false
先给出判断两个树是否相等的代码(递归):
bool _isSubtree(struct TreeNode* root1,struct TreeNode* root2){
if(root1==NULL&&root2==NULL){
return true;
}
if((root1==NULL||root2==NULL)||root1->val!=root2->val){
return false;
}
return _isSubtree(root1->left,root2->left)&&_isSubtree(root1->right,root2->right);
}
解析:如果(root1==NULL&&root2==NULL),说明此时两个树都为空树,那么返回true,表示两树相同。如果(root1==NULL||root2==NULL),那么此时两个树一定一个为空,另一个不为空,此时两个树不相同,返回false;如果两个树的根节点的值不同,那么此时两个树也不相同,依旧返回false;检测完成后再利用递归来依次检测两树的左子树和右子树是否相同,注意条件必须是&&。
注意:递归代码不好理解,可以给出两个简单的两个树,然后利用上述代码的思想进行比较,加深理解。
完成了比较两个数是否相等的代码后,那么这道题就很简单了,按照题目的意思,一棵树为另一棵树的子树,那么子树不能是原来的树的中间部分,子树只能是最后的部分,或者两棵树完全相等。所以我们只要依次调用上述函数就可以完成改题目,具体过程如下:
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){
if(root==NULL&&subRoot==NULL){
return true;
}
if(root==NULL){
return false;
}
return _isSubtree(root,subRoot)||isSubtree(root->left,subRoot)||isSubtree(root->right,subRoot);
}
解析:如果两个树都为空,那么满足题目要求,返回true;如果只是root==NULL,那么一定不满足题目要求,返回false;然后就可以调用比较两个树是否相等的函数了,再利用递归,依次比较subRoot指向的树是否是root指向的树的左子树或者右子树的子树就可以了。