题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
思路步骤:
1、先找到树A中与树B根节点相等的节点,称该部分子树为树P
2、比较树B是不是树P的子树
注意:要考虑到树A中可能存在多个与B的根节点相等的节点,对此进行处理。
class Solution {
public:
bool zi1(TreeNode* a,TreeNode* b) 寻找二叉树树A中,与二叉树B根节点的值相同的节点
{
bool flag = false;
if(a == NULL || b == NULL) return false; // 1、B为空树则返回false
// 2、若树A不断将左右节点带入函数递归,但直到根节点也没有找到符合要求(与B的根节点相等)的节点,则在下一次递归中返回false
if(a->val == b->val) // 若找到符合要求(与B的根节点相等)的节点,则将该子树部分称呼为树P,执行函数zi2
{
// 考虑到树A中可能存在多个与B的根节点相等的节点,这些节点的子树都需要与B树进行比较
// 所以不能直接返回 函数执行结果作为最终的判断结果,而是需要再判断一下
if(flag = zi2(b,a)) return flag; // 若结果为true,则直接返回即可
// 若结果为false,则与其左右子树的递归结果取或运算后再返回
}
bool lflag = zi1(a->left,b); // 不断将左右节点带入函数递归
bool rflag = zi1(a->right,b);
return flag || lflag || rflag; // flag,lflag,rflag 中只要有一个为真,那么返回结果就为真
}
bool zi2(TreeNode* b,TreeNode* p) // 判断树B是否为树P的子树
{ // 对于树B中的每一个非空节点,都需要与树P中对应的节点相等才能称其为子树
// 因此需要将树B与树P上每一个位置对应的节点都带入函数递归判断
if(b == NULL) return true; // 若在某一次递归中,若树B对应的位置已经为空,则返回true
if(p == NULL) return false; // 若在某一次递归中,若树B对应的位置已经不为空,但树P对应的位置已经为空,则返回false
return (b->val == p->val) && zi2(b->left,p->left) && zi2(b->right,p->right);
// 若都不为空,则返回 两节点的比较结果 跟 其左右节点代入函数zi2的结果 的与运算
// 这样保证只有全部结果均为真,才返回真
}
bool HasSubtree(TreeNode* A, TreeNode* B)
{
return zi1(A,B);
}
};