【LeetCode】剑指 Offer 26. 树的子结构 - Go 语言题解


一、题目描述

输入两棵二叉树 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 的子结构有两种可能性:

  • 树 B 是树 A 的上半结构:如果树 B 的节点和树 A 节点相等,这时如果按照广度优先遍历两树,按层次,那么两树的队列顺序一定一致,一直对比两队列直到树 B 结束就说明相等。
  • 树 B 是树 A 的下半结构:这时,树 B 是树 A 的子树,这时按照广度优先的话,两树的队列就不相等(因为层数不同),这时使用深度优先遍历,如果遇到树 A 中和树 B 根节点值相等的节点,就使用递归再对比他们的左右子树是否相等。

我的方法就是先判断树 B 是否是树 A 的上半结构,如果不是,再判断树 B 是否是树 A 的下半结构:

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func isSubStructure(A *TreeNode, B *TreeNode) bool {
    if A == nil || B == nil{
        return false
    }

    que := []*TreeNode{A}
    qub := []*TreeNode{B}
    i := 0
    tag := false

    //如果子树 B 的根节点和树 A 相等,那么 B 有可能是 A 树的上半结构,这时广度优先、层次遍历就行
    for i < len(que) && i < len(qub) && que[i].Val == qub[i].Val {
        tag = true

        if que[i].Left != nil{
            que = append(que,que[i].Left)
        }
        if que[i].Right != nil{
            que = append(que,que[i].Right)
        }

        if qub[i].Left != nil{
            qub = append(qub,qub[i].Left)
        }
        if qub[i].Right != nil{
            qub = append(qub,qub[i].Right)
        }
        i++
    }
    //将子树 B 遍历完了,证明子树 B 真的是 A 树的上半结构
    if tag == true && i == len(qub){
        return true
    }

	//如果不是上半结构,进入 B 树是 A 树的下半结构的判断,下半结构的判断使用深度优先遍历(递归)
    for i < len(que) {
        if que[i].Val == B.Val && issubtequal(que[i].Left , B.Left) && issubtequal(que[i].Right , B.Right){
            return true
        }
        if que[i].Left != nil{
            que = append(que,que[i].Left)
        }
        if que[i].Right != nil{
            que = append(que,que[i].Right)
        }
        i++
    }
    return false
}


func issubtequal(A *TreeNode, B *TreeNode) bool{
    if A == nil && B == nil{
        return true
    }else if A != nil && B == nil{
        return false
    }else if A == nil && B != nil{
        return false
    }else{
        if A.Val == B.Val{
            return issubtequal(A.Left,B.Left) && issubtequal(A.Right,B.Right)
        }else{
            return false
        }
    }
}

评判结果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值