剑指Offer刷题笔记——树的子结构

输入两颗二叉A,B,判断B是不是A的子结构。(PS:我们约定空不是任意一个树的子结构)。

这题思路还是挺清晰的:递归比较两个树的结点值。

具体应该分为两个步骤:首先在A中找到子树的开始。也就是在A树中找到和B根节点数值相同的结点,只有找到了这个结点,才能进行第二步,向下一层一层去比较。

HasSubTree函数主要是在A里找B的根节点。找到了之后用IsSame函数比较两个子树。两个函数都是递归调用的,但是要注意逻辑的顺序:用result变量记录搜索的状态。如果根结点下子树不同,搜索左子树,如果搜索左子树没有找到,再搜索右子树。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def HasSubtree(self, pRoot1, pRoot2):
        # write code here
        result = False
        if pRoot1==None or pRoot2==None:
            return False
        if pRoot1.val == pRoot2.val:
            result = self.IsSame(pRoot1,pRoot2)
        if not result:
            result = self.HasSubtree(pRoot1.left, pRoot2)
        # 判断左子树没找到,接着找右子树。
        # 如果没有这个判断,右子树结果会覆盖左子树结果。
        if not result:
            result = self.HasSubtree(pRoot1.right, pRoot2)
        return result 
    def IsSame(self,pRoot1,pRoot2):
        # 必须先判断B,如果AB同时为空,先判断A树返回为假
        if pRoot2==None:
            return True 
        # 如果A树为空,B不为空,就得提前退出
        if pRoot1== None:
            return False
        if pRoot1.val == pRoot2.val:
            # 这是需要判断数值是不是相等,所以二者之间没有关系。
            p1 = self.IsSame(pRoot1.left,pRoot2.left)
            p2 = self.IsSame(pRoot1.right,pRoot2.right)
        else:
            return False
        # 返回是这个子树是不是相等,所以左右子树要取交集
        return p1 and p2

 下面这是网上大神的代码,思路是一样的,但是简洁了很多。

https://cuijiahua.com/blog/2017/12/basis_17.html

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def HasSubtree(self, pRoot1, pRoot2):
        # write code here
        if not pRoot1 or not pRoot2:
            return False
        # 这一坨返回的意思是有三种情况:当前结点就是B的根结点、在左子树里找、在右子树里找。
        return self.HasSubtree(pRoot1.left, pRoot2) or self.HasSubtree(pRoot1.right, pRoot2) or self.is_subtree(pRoot1, pRoot2)
    def is_subtree(self, A, B):
        if not B:
            return True
        if not A or A.val != B.val:
            return False
        return self.is_subtree(A.left, B.left) and self.is_subtree(A.right, B.right)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值