题目:
输入两棵二叉树A和B,判断B是不是A的子结构。
1.解题思路:
- 第一步:在树A中找到和B的根节点的值一样的节点R;
- 第二步:判断树A中以R为根节点的子树是不是包含和树B一样的结构;
- 可以使用递归的方法,递归的终止条件是到达了树A或者树B的叶节点;
- 要注意空指针的处理。
2.代码:
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution{
public:
//判断根节点
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2){
//赋初值
bool result = false;
//二叉树不为空
if(pRoot1 != nullptr && pRoot2 != nullptr){
//A中找到和B的根节点的值一样的节点,则去判断左右节点
if(pRoot1->val == pRoot2->val) result = DoesTree1HasTree2(pRoot1, pRoot2);
//如果左右未匹配,则继续遍历A的左叶节点
if(!result) result = HasSubtree(pRoot1->left, pRoot2);
//如果左右仍未匹配,则继续遍历A的右叶节点
if(!result) result = HasSubtree(pRoot1->right, pRoot2);
}
return result;
}
private:
//判断左右叶节点是否匹配
bool DoesTree1HasTree2(TreeNode* pRoot1, TreeNode* pRoot2){
//到达B的叶节点,说明匹配成功
if(pRoot2 == nullptr) return true;
//到达A的叶节点(B的叶节点还没到达),匹配失败
if(pRoot1 == nullptr) return false;
//节点值不相同时,匹配失败
if(pRoot1->val != pRoot2->val) return false;
//判断左右叶节点是否相同
return DoesTree1HasTree2(pRoot1->left, pRoot2->left) && DoesTree1HasTree2(pRoot1->right, pRoot2->right);
}
};
简洁版(短路特性):
class Solution{
public:
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2){
//只要有个二叉树为空, 则匹配失败
if(pRoot1 == nullptr || pRoot2 == nullptr) return false;
//第一个为真的话 后面不用运行
return helper(pRoot1, pRoot2) || HasSubtree(pRoot1->left, pRoot2) || HasSubtree(pRoot1->right, pRoot2);
}
bool helper(TreeNode* A, TreeNode* B){
//如果B到达叶节点,则匹配成功
if(B == nullptr) return true;
if(A == nullptr) return false;
//如果根节点相同
if(A->val == B->val){
//继续判断左右节点
return helper(A->left, B->left) && helper(A->right, B->right);
}
else return false;
}
};