剑指offer -17 树的子结构

剑指offer-17 树的子结构

一、题目描述

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

输入:{8,8,#,9,#,2,#,5},{8,9,#,2}

输出:true

母树A:                                   子树B: 

             


二、解题步骤


1.解题思路

如果树B是树A的子结构,则子树的根节点可能是母树的任意一个节点,因此判定是否是子结构需要进行两步判断:

(1)先序遍历树 A 中的每个节点 n
​    
(2)判断树A中以n为根节点的子树,是否包含树B。

终止条件:
当节点 B 为空:说明树 B 已匹配完成(越过叶子节点),因此返回 true;
当节点 A为空:说明已经越过树 A叶子节点,即匹配失败,返回 false;
当节点 A和 B的值不同:说明匹配失败,返回 false ;


2.代码实现

# -*- 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
        result=False
        if pRoot1==None or pRoot2 ==None:
            return False
        #查看A,B的根节点是否相同
        if pRoot1.val ==pRoot2.val:
            result=self.helper(pRoot1,pRoot2)
        if not result:
            #将pRoot的左子树与pRoot2开始递归
            result=self.HasSubtree(pRoot1.left, pRoot2) 
        if not result:
            #将pRoot的右子树与pRoot2开始递归
            result=self.HasSubtree(pRoot1.right, pRoot2)
        return result
    def helper(self,node1,node2):
        #如果pRoot2是一个叶子节点或者是提前到达了叶子节点说明已经遍历结束
        if node2==None:
            return True
        #如果是pRoot1先到达叶子节点,说明已经遍历完,此时pRoot2还没有遍历完
        if node1==None:
            return False
        #如果此时的两个节点的值是相等的,则进入左子树与右子树值的判断
        if node1.val==node2.val:
            if  self.helper(node1.left,node2.left)and self.helper(node1.right,node2.right):
                return True
        else:
            return False

3. 总结

      判定是否是树的子结构,递归的使用非常关键,树不仅是要数值最重要的是结构也需要相同。

     所以第一步要是找出A、B两棵树中是否有值相同的节点,先判断根节点的值是否相同,相同则进入下一步helper()函数。如果两棵树根节点的值不同,则需要使用递归将A的左子树与B进行判断,如果遇到相同的点则进入下一步helper()函数。如果此时还没有判断出来,则需要对A的右子树与B进行判断,判定在A的右子树中是否有与B值相同的点。

   第二步是进入到helper()函数,此函数的作用是判断进入此函数的两棵树是否有相同的结构,不仅要数值相同,而且结构也需要相同。需要注意的地方是首先判断传入函数的第二棵树是否是叶子节点,这里需要着重了解一下,因为在第一个函数HasSubtree()中进行了判断,如果A树的节点与B树的节点有相同的则进入到helper()函数中,进入到helper()函数中时,肯定是B的根节点与A的某一个节点是相同的,所以将以A的某个节点为根节点的结构与整个B树一同传进了helper()中,如果此时的B 仅仅是一个叶子节点,那B肯定是A的子结构,因为数值相同,并且是叶子节点;如果传进来的是A的一个叶子节点,但是此时B不为空,那肯定B就不是A的子结构;下面的需要注意一下,是判断两个值是否是相同的,这个判断值是否相同是在第一个函数中判断过了,此时需要判断的原因是需要进行递归,判断传入的树的左子树与B的左子树相同(值相同,结构相同)并且传入的树的右子树与B的右子树相同,那肯定就符合子结构的定义,返回True。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值