输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。
例如:
给定的树 A:
3
/ \
4 5
/ \
1 2
给定的树 B:
4
/
1
返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。
示例 1:
输入:A = [1,2,3], B = [3,1]
输出:false
示例 2:
输入:A = [3,4,5,1,2], B = [4,1]
输出:true
限制:
0 <= 节点个数 <= 10000
解题思路:
若B是A的子结构,则子结构的根结点可能为树A的任意一个结点。所以可以通过先序遍历树A中的每个结点,并且判断以该结点为根结点的子树是否包含树B。
算法流程:
1.排除树A为空或树B为空的情况并且前序遍历树A并判断以该结点为根结点的子树是否包含树B。(前序遍历用递归实现)
2.定义判断以该结点为根结点的子树是否包含树B的函数recur(传入树A和树B)
如果树B为空(说明树A包含树B)
返回true
如果树A为空或者树A的值不等于树B的值
返回false
如果A的值定义B的值,还需判断B的左子树是否为A的左子树的子结构,B的右子树是否为A的右子树的子结构,用前序遍历判断
代码:
class Solution {
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
return (A!=nullptr&&B!=nullptr)&&
(recur(A,B)||isSubStructure(A->left,B)||
isSubStructure(A->right,B));
}
bool recur(TreeNode* A,TreeNode* B)
{
if(B==nullptr)
return true;
if(A==nullptr||A->val!=B->val)
return false;
return recur(A->left,B->left)&&
recur(A->right,B->right);
}
};
运行步骤:
给定的树 A:
3
/ \
4 5
/ \
1 2
给定的树 B:
4
/
1
判断以3为根结点的树A是否包含以4为根结点的树B
recur(3,4),3!=4,返回false
判断以4为根结点的树A是否包含以4为根结点的树B
recur(4,4),4=4,1=1,B为空,返回true
因为是 || (或运算符),所以后面都不要执行了,返回true。