剑指offer - 树的子结构 - python

48 阅读2分钟

题目描述:

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

思路:

  • 递归法: 对于给定的两棵二叉树来判断B是否是A的子结构,要充分考虑以下几种情形:

    • 若A和B中有一棵为空则两者之间必不存在结构,返回False
    • 若A和B均不为空,则要先在A中找到和B根节点相同的节点,然后判断它们的子节点是否相同,直到到达A或B的叶子节点
    • 根据二叉树本身的性质,整个过程可以使用递归完成
  • 先序遍历法:如果B是A的子结构,那么B的先序遍历结果就是A的先序遍历结果的一部分。因此可以先通过先序遍历获取两棵树的遍历结果,然后进行即可


AC代码

递归法

# -*- 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
        def hasEqual(root1, root2):
            # 若小树只有相同的根节点,则返回True
            if root2 == None:
                return True
			# 如果大树只有根节点,而小树还有子节点,返回False
            if root1 == None:
                return False
            
            # 若根节点相同
            if root1.val ==root2.val:
                # 如果小树不存在左子树,表示已判断部分相同,子结构成立,返回True
                if root2.left == None:
                    leftEqual = True
                else:
                    # 往下递归判断
                    leftEqual = hasEqual(root1.left, root2.left)
                # 如果小树右节点为空,判断终止,已判断部分相同,子结构成立,返回True
                if root2.right == None:
                    rightEqual = True
                else:
                    # 往下递归判断
                    rightEqual = hasEqual(root1.right, root2.right)
                
                # 如果都为True说明子结构成立
                return leftEqual and rightEqual
            
            # 如果当前节点为根节点都不同,直接返回False
            return False
        
        # 如果有一棵为空直接返回False     
        if pRoot1 == None or pRoot2 == None:
            return False
        
        # 如果A和B的根节点就相同,递归判断子节点
        if pRoot1.val == pRoot2.val:
            ret = hasEqual(pRoot1, pRoot2)
            if ret:
                return True
        # 在A的左子树找和B的根节点相同的子节点再进行判断  
        ret = self.HasSubtree(pRoot1.left, pRoot2)
        if ret:
            return True
        
        # 在A的右子树找和B的根节点相同的子节点再进行判断
        ret = self.HasSubtree(pRoot1.right, pRoot2)
        return ret

先序遍历法

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def __init__(self):
        self.res1 = []
        self.res2 = []
        
    def HasSubtree(self, pRoot1, pRoot2):
        # write code here
        def preOrder(flag, root):
            if root == None:
                return None
            if flag == 1:
                self.res1.append(root.val)
            else:
                self.res2.append(root.val)
            preOrder(flag, root.left)
            preOrder(flag, root.right)

        if pRoot1 == None or pRoot2 == None:
            return False
        
        preOrder(1, pRoot1)
        preOrder(2, pRoot2)
        
        for i in range(len(self.res1)):
            if self.res1[i] == self.res2[0] and self.res1[i:i + len(self.res2)] == self.res2:
                return True
            
        return False