【剑指Offer】面试题18:树的子结构
2017-07-26 19:44
537 查看
思路整理自剑指Offer
一:题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
二:解题思路
要查找树A中找到和树B结构一样的子树:
第一步:在树A中找到和B的根节点的值一样的结点R
第二步:判断树A中以R为根节点的子树是不是包含树B一样的结构
以一个例子进行说明:
1.我们在树A中找到值为8的结点:从A的根节点开始遍历,我们发现它的根节点的值就是8
2.接着我们就去判断树A的根节点下面的子树是否含有和树B一样的结构。
3.在树A中,根节点的左子树的值是8,而树B的根节点的左子树结点是9,对应的两个结点不同。
4.因此我们仍然要遍历树A,接着查找的值为8的结点,我们在树的第二层找到一个值为8的结点
5.判断该结点下面的子树是否含有和B树一样结构的子树,先后找到两个结点9,2,这和树B的结构完全相同。因此树B是树A的子结构
以一个例子说明:
三:代码实现
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
bool DoesTree1HaveTree2(TreeNode* pRoot1, TreeNode* pRoot2){
//树B遍历完,则说明树B是以pRoot为根节点的子树,是A的子树
if(pRoot2==NULL)
return true;
//如果B还没有遍历结束,pRoot1就已经遍历完,则B不是子树
if(pRoot1==NULL)
return false;
//如果对应结点不相等,则B不是子树
if(pRoot1->val!=pRoot2->val)
return false;
//如果当前对应结点符合条件,则分别遍历左子结点和右子节点
return DoesTree1HaveTree2(pRoot1->left,pRoot2->left) && DoesTree1HaveTree2(pRoot1->right,pRoot2->right);
}
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
{
bool result=false;
//在每一处需要访问地址的时候都要问自己这个地址有没有可能是NULL,如果是NULL,如何处理
if(pRoot1==NULL || pRoot2==NULL)
return result;
//如果A的R节点与B的根节点相同,那么我们要判断A中以R结点为根节点的子树是否包含和树B一样的结构
if(pRoot1->val==pRoot2->val)
result=DoesTree1HaveTree2(pRoot1,pRoot2);
//如果R为根节点的子树不包含B,则继续遍历A,寻找与B树根节点相同的结点
//左子结点
if(!result)
result=HasSubtree(pRoot1->left,pRoot2);
//右子节点
if(!result)
result=HasSubtree(pRoot1->right,pRoot2);
return result;
}
};
一:题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
二:解题思路
要查找树A中找到和树B结构一样的子树:
第一步:在树A中找到和B的根节点的值一样的结点R
第二步:判断树A中以R为根节点的子树是不是包含树B一样的结构
以一个例子进行说明:
1.我们在树A中找到值为8的结点:从A的根节点开始遍历,我们发现它的根节点的值就是8
2.接着我们就去判断树A的根节点下面的子树是否含有和树B一样的结构。
3.在树A中,根节点的左子树的值是8,而树B的根节点的左子树结点是9,对应的两个结点不同。
4.因此我们仍然要遍历树A,接着查找的值为8的结点,我们在树的第二层找到一个值为8的结点
5.判断该结点下面的子树是否含有和B树一样结构的子树,先后找到两个结点9,2,这和树B的结构完全相同。因此树B是树A的子结构
以一个例子说明:
三:代码实现
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
bool DoesTree1HaveTree2(TreeNode* pRoot1, TreeNode* pRoot2){
//树B遍历完,则说明树B是以pRoot为根节点的子树,是A的子树
if(pRoot2==NULL)
return true;
//如果B还没有遍历结束,pRoot1就已经遍历完,则B不是子树
if(pRoot1==NULL)
return false;
//如果对应结点不相等,则B不是子树
if(pRoot1->val!=pRoot2->val)
return false;
//如果当前对应结点符合条件,则分别遍历左子结点和右子节点
return DoesTree1HaveTree2(pRoot1->left,pRoot2->left) && DoesTree1HaveTree2(pRoot1->right,pRoot2->right);
}
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
{
bool result=false;
//在每一处需要访问地址的时候都要问自己这个地址有没有可能是NULL,如果是NULL,如何处理
if(pRoot1==NULL || pRoot2==NULL)
return result;
//如果A的R节点与B的根节点相同,那么我们要判断A中以R结点为根节点的子树是否包含和树B一样的结构
if(pRoot1->val==pRoot2->val)
result=DoesTree1HaveTree2(pRoot1,pRoot2);
//如果R为根节点的子树不包含B,则继续遍历A,寻找与B树根节点相同的结点
//左子结点
if(!result)
result=HasSubtree(pRoot1->left,pRoot2);
//右子节点
if(!result)
result=HasSubtree(pRoot1->right,pRoot2);
return result;
}
};
相关文章推荐
- 剑指Offer面试题18树的子结构(递归),面试题19二叉树的镜像(递归和非递归用栈)
- 剑指offer——面试题18:树的子结构
- 【面试题】剑指Offer-18-判断一颗树是否为另一颗树的子树
- 剑指Offer之面试题18:树的子结构
- 剑指offer之面试题18:树的子结构
- 剑指offer-面试题18 判断二叉树B是不是二叉树A的子结构
- 剑指Offer_面试题18_树的子结构
- 剑指offer 面试题18 判断二叉树B是否是A的子结构
- [剑指offer]面试题18:树的子结构
- 剑指Offer面试题:18.二叉树的镜像
- 剑指Offer面试题18:删除链表的节点
- 【面试题】剑指offer18--判断一个二叉树是否为另一个二叉树的子结构
- 【剑指offer】面试题18:树的子结构
- 剑指offer--面试题18:删除链表的结点
- 剑指offer 面试题18 树的子结构
- 剑指Offer 面试题18:删除链表节点 Java代码实现
- 剑指offer之面试题18:树的子结构
- 剑指offer面试题18-树的子结构
- 剑指offer-面试题 18:树的子结构
- 剑指offer面试题18-:树的子结构