输入两颗二叉树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)