剑指Offer 26 树的子结构

剑指Offer 26 树的子结构

题目描述: 输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构) B是A的子结构, 即 A中有出现和B相同的结构和节点值。LeetCode链接

image-20210821214236986

首先,这个题要和判断B树是不是A树的子树区分

  • 如下左图所示,t 既是s的子结构也是s的子树
  • 如下右图所示,t只是s的子结构而不是s的子树(因为t不包含s中以4为根节点子树的全部,即0号节点)

image-20210821214809425

**过程分析:**如果B是A的子结构,那么就需要判断A树中以任意一个节点为根的子树有没有包含B,因此就要遍历A树的每一个节点Na,然后判断以Na为根的子树有没有包含B树。

具体过程:

  • 首先判断两个树的 根节点A、B是否为空,如果A或B为空,或者AB均为空,那么B一定不是A的子结构

  • 如果AB均不为空,分三种情况讨论

    • 以A为根节点的子树包含B

      image-20210821221930978
    • 以A的左孩子为根节点的子树包含B

      image-20210821222006740
    • 以A的右孩子为根节点的子树包含B

      image-20210821222021638
  • 判断当前节点为根的子树是否包含B

    • 如果B为空,说明B树已经遍历结束,匹配成功

      如下所示,当B指向①,即B为空时,说明B已经遍历结束,那么说明A树中以当前节点为根的子树包含B

      image-20210821222626657
    • 如果A为空(B不为空),说明A中不包含这个节点,匹配失败

      如下图所示,当B指向①,B为3,但是②已经为空,那么说明A树中以当前节点为根的子树不包含B

      image-20210821222832950
    • 如果AB均不为空,判断其值是否相同

      • 如果不同,匹配失败

        如下所示,当AB均不为空,但其值不同,那么说明A树中以当前节点为根的子树不包含B

        image-20210821223035893
      • 如果相同,判断当A的左孩子和B的左孩子是否有相同子结构,并且还要判断A的右孩子和B的右孩子是否有相同子结构,依次递归。如果两者子树均相同,那么说明A树中以当前节点为根的子树包含B。

代码实现:

 public boolean isSubStructure(TreeNode A, TreeNode B)
    {
        //根据题意,如果A为空 或 B为空 或AB均为空(两个是空树),则一定不是子结构
        if (A == null || B == null)
        {
            return false;
        }
   //如果以节点A为根节点的子树包含树B 或者  以节点A的左孩子为根节点的子树包含树B 或者 以节点A的右孩子为根节点的子树包含树B
        return isSameTree(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B);
    }


    public static boolean isSameTree(TreeNode aNode, TreeNode B)
    {
      	//如果B为空,说明B树已经匹配完成
        if (B == null)
        {
            return true;
        }
        //如果a为空,b不为空或者ab均不为空,但其值不同,说明匹配失败
        if (aNode == null || aNode.val != B.val)
        {
            return false;
        }
        //如果ab均不为空,且值相同,递归判断其叶子节点
        return isSameTree(aNode.left, B.left) && isSameTree(aNode.right, B.right);
    }

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值