1-Description
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构),二叉树结点定义如下:
//Definition for binary tree struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} };
2-Solution
这道题的思路可以分为两步:
- 在树A中找到和树B的根节点值相同的结点R;
- 判断树A中以R为根结点的子树是否包含和树B一样的结构。
现以下面的两棵树为例进行分析(左边为A,右边为B):
1-首先试着在A中找找值为8的结点(树B的根结点),从树A的根节点开始遍历,发现树A的根节点就是8,接着再判断A的根结点下的子树是不是含有和树B一样的结构,因为树A根结点的左子树为8,而树B的根节点左子树为9,对应的两个结点不相同,所以需要继续往下遍历。
2-接着往下继续查找与B的根结点值相同的结点,显然在树A的第二层找到了这样一个结点,找到该结点之后继续进行第二步判断,即判断这个结点以下的子树是否含有和树B一样的结构的子树。显然通过遍历我们找到了和树B具有相同结构子树。
注意这里查找值相同的结点值相当于树的遍历,依据以上的思路利用递归可以完成以下代码:
class Solution {
public:
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2){
bool result = false;
if(pRoot1 != NULL && pRoot2 != NULL){//只有当A与B均不为空时,才进遍历,否则直接false
if(pRoot1->val == pRoot2->val) result = IsContain(pRoot1,pRoot2);//有相同的结点则进行判断是否是子树
if(!result) result = HasSubtree(pRoot1->left,pRoot2);//如果没有找到相同结点则继续往下递归
if(!result) result = HasSubtree(pRoot1->right,pRoot2);
}
return result;
}
bool IsContain(TreeNode* pRoot1, TreeNode* pRoot2){
if(pRoot2 == NULL) return true;//遍历完B树,说明B是A的子树(关键)
if(pRoot1 == NULL) return false;//B还没遍历完,A已经遍历完,说明B不是A的子树(加强鲁棒性)
if(pRoot1->val != pRoot2->val) return false;//其中有不相等的结点直接false
return IsContain(pRoot1->left,pRoot2->left) && IsContain(pRoot1->right,pRoot2->right);
}
};