时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
知识铺垫:
先来看下子树和子结构的概念
子树:只要包含了一个节点,就得包含这个节点下的所有节点
子结构:包含了一个节点,可以只取左子树或右子树,或者不取,强调结构上的一致
(可参考:https://blog.csdn.net/wushuomin/article/details/79943737)
思路:
一颗大树A,一颗小树B,首先判断A的根节点是否与B的根节点相同,不相同,就依次去A根节点的左子树、右子树上查找,如果存在(假设A中与B的根节点相等的节点为D),此时需要判断的就是D的左子树、右子树是否与B的根节点的左子树、右子树相同节点结构,终止条件:如果B先访问到头了,即小树B先达到NULL,说明B就是A的子结构,如果大树A达到NULL,说明就不是A的子结构。
采用递归的方式
/*
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 != NULL && pRoot2 != NULL)
{
if(pRoot1->val == pRoot2->val)
{
//该根节点作为起点判断是否包含pRoot2
result = judgeSubTree(pRoot1,pRoot2);
}
//如果没有找到,就去该节点的左子树中找
if(!result)
{
result = HasSubtree(pRoot1->left,pRoot2);
}
//如果还没有找到,就去该节点的右子树中找
if(!result)
{
result = HasSubtree(pRoot1->right,pRoot2);
}
}
return result;
}
private:
bool judgeSubTree(TreeNode *node1,TreeNode *node2)
{
if(node2 == NULL)
return true;
if(node1 == NULL)
return false;
if(node1->val != node2->val)
{
return false;
}
return judgeSubTree(node1->left,node2->left)
&& judgeSubTree(node1->right,node2->right);
}
};
在judgeSubTree函数中对node1->val 与node2->val判断是否相等是有必要的,应为该函数是一个递归函数,下面递归调用的时候,还是要判断传进去的两个节点的值是否相等另一种写法:
/*
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)
{
if(pRoot1 == NULL || pRoot2 == NULL)
{
return false;
}
return judeSubTree(pRoot1,pRoot2)
|| judeSubTree(pRoot1->left,pRoot2)
||judeSubTree(pRoot1->right,pRoot2);
}
bool judeSubTree(TreeNode* node1,TreeNode * node2)
{
if(node2 == NULL)
return true;
if(node1 == NULL)
return false;
if(node1->val != node2->val)
return judeSubTree(node1->left,node2) ||
judeSubTree(node1->right,node2);
return judeSubTree(node1->left,node2->left)&&
judeSubTree(node1->right,node2->right);
}
};
子结构包含与子树,子树会要求更加严格,不仅结构相同,节点的值也要相同,只需要对其值判断相等,不能就直接返回false即可
判断是否为子树:
/*
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)
{
if(pRoot1 == NULL || pRoot2 == NULL)
{
return false;
}
return judeSubTree(pRoot1,pRoot2)
|| judeSubTree(pRoot1->left,pRoot2)
||judeSubTree(pRoot1->right,pRoot2);
}
bool judeSubTree(TreeNode* node1,TreeNode * node2)
{
if(node2 == NULL)
return true;
if(node1 == NULL)
return false;
if(node1->val != node2->val)
return false;
return judeSubTree(node1->left,node2->left)&&
judeSubTree(node1->right,node2->right);
}
};
来源:https://www.cnblogs.com/whiteBear/p/12523524.html