树的子结构
树的子结构
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
这里要说一下这里的"子结构"和“子树”有什么区别。简单来说就是,子结构可以说子树或者子树的一部分,它也要求和原树的对应是连续的,但是可以不到叶子层
思路:用递归来实现,从 A 树的根节点开始,判断其所有的节点是不是依次和树 B 相同,如不同,递归调用函数,继续判断树 A 当前节点的左子树的所有节点或右子树的所有节点是否和树 B 所有节点相同,直到遍历到父树 A 的叶子节点,如果不是完全相同,则树 B 不是树 A 子树,如果直到遍历到树 B 的叶子节点,其所有节点在树 A 中均有,则树 B 是树 A 的子树。
isSubtree(root1 , root2) || HasSubtree(root1.left , root2) || HasSubtree(root1.right , root2);
// 判断树 A 所有的节点是不是依次和树 B 相同,或树 A 的左子树的所有节点或右子树的所有节点 是否和树 B 所有节点相同
isSubtree (root1.left , root2.left) && isSubtree ( root1.right , root2.right );
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
if(root1==null||root2==null){
return false;
}
/*
这里必须用或,因为可能有多个地方“有可能”能对上,所以需要通过递归和或运算多处尝试,只要有一个能对上就是true.
*/
return isSubtree(root1,root2)||HasSubtree(root1.left,root2)||HasSubtree(root1.right,root2);
}
public boolean isSubtree(TreeNode root1,TreeNode root2){
/*
递归出口,如果递归到子树完了,就说明全部都对上了。如果是原树完了而子树没完,那就说明没对上
*/
if(root2==null){
return true;
}
if(root1==null){
return false;
}
if(root1.val==root2.val){
return isSubtree(root1.left,root2.left)&&isSubtree(root1.right,root2.right);
}
/*
如果以上情况都不是,那就是没对上
*/
return false;
}
}
这种二叉树类型的问题,使用递归最适合,但是非递归有时也必须会
注意,上面的写法是有讲究的:
if(root2==null){
return true;
}
if(root1==null){
return false;
}
不能换成:
if(root1==null){
return false;
}
if(root2==null){
return true;
}
if先判断哪个,后判断哪个,都是有隐含意义的:先判断root2,只要它为null,则无论root1是否是null都是配对完成了,但是先判断root1的话会错判root2同时为null的情况。这一点要注意。
我又重写了一下,对算法有了一些更好的思考,能够从算法设计的角度来理解了
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
//重造一个函数用于递归是为了避免开始时候检测root2是否为空和递归时检测root2是否为空的逻辑相反造成冲突
public boolean HasSubtree2(TreeNode root1,TreeNode root2){
if(root1==null){
if(root2==null){
return true;
}else{
return false;
}
}
//递归中,root2是null是true的条件,和初始时是相反的
if(root2==null){
return true;
}
if(root1.val==root2.val){
return ((HasSubtree2(root1.left,root2.left)&&HasSubtree2(root1.right,root2.right))||HasSubtree2(root1.left,root2)||HasSubtree2(root1.right,root2));
}else{
return (HasSubtree2(root1.left,root2)||HasSubtree2(root1.right,root2));
}
}
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
//初始时对特殊情况进行检测
//初始时要求root2不能是null
if(root2==null){
return false;
}
if(root1==null){
return false;
}
return HasSubtree2(root1,root2);
}
}

浙公网安备 33010602011771号