《剑指offer》刷题系列——(三十一) 树的子结构

16 篇文章 0 订阅
16 篇文章 0 订阅

题目

输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。
在这里插入图片描述

思路

遇到这个题,我们的比较思路是,从A的根节点开始,寻找与B的根节点值相同的节点,如果找到了,那么这个节点作为根节点形成的树就有可能包含B的结构。当我们找到这个可能的节点,再将它的结构与B进行比较。
我们需要完成两个过程,分别定义在两个函数中,一个是在A中查找可能包含B的子结构isSubStructure(),另一个是比较该子结构与B树是否含有相同的结构compareTree()。

isSubStructure()函数:
功能是在A中寻找与B的值相同的节点
(1)如果当前根节点 与 B 的节点值相同,就可以通过compareTree()函数比较该树是否有与B相同的子结构;
找到了返回True,
(2)如果 当前根节点 与 B 的节点值不同,就在当前根节点的左子树中查找;如果 左子树中没有找到,就在当前根节点的右子树中寻找,左子树和右子树中只要有一个找到就可以返回True.
结束条件:
如果A为空,则遍历完了所有A的节点都没有找到与B的节点值相同的节点,返回false。
如果B为空,根据题目要求,空树不是任意一个树的子结构,返回false。

compareTree()函数:
如果A.val等于B.val,就去递归比较A和B的左右子树的结构是否相同,只有左右子树结构都相同时才返回True.
如果A.val不等于B.val,说明它们的节点值不相同,返回False。
结束条件:
如果B为空,说明B前面已经逐个比较完了所有的节点,并且都和A的结构匹配,此时返回True。
如果A为空,说明A直到查找到它的叶子结点也没有找到与B相匹配的结构,此时返回False。

代码

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool:
        if not A or not B: return False
        if A.val==B.val and self.compareTree(A,B): 
            return True
        if self.isSubStructure(A.left,B): return True
        if self.isSubStructure(A.right,B): return True
        return False
        
    def compareTree(self,A,B):
        if not B: return True
        if not A: return False
        if A.val!=B.val: return False
        return self.compareTree(A.left,B.left) and self.compareTree(A.right,B.right)

复杂度

时间复杂度 O(MN) : 其中 M,N分别为树 A和 树 B的节点数量。
空间复杂度 O(M) : 当树 A和树 B都退化为链表时,递归调用深度最大。当 M≤N时,遍历树 A与递归判断的总递归深度为 M;当 M>N时,最差情况为遍历至树 A叶子节点,此时总递归深度为 M。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值