问题
思路
二叉树的前序遍历 + 递归
遍历树A的每一个节点,判断是否与树B部分重合。这里的部分重合指的是树A的头节点与树B的头节点相等,且树A的左右子数能够包含树B的左右子树。
Python实现
先写一个函数,判断树A与树B是否满足上述的「部分重合」的关系:
def dfs(A: TreeNode, B: TreeNode) -> bool:
# B已经遍历完了(这里看起来不符合题目的「空树不是任何树的子树」,待会儿再解释)
if B is None:
return True
# B还没有遍历完,A为空了,肯定A不能包含B了
if A is None:
return False
# 二叉树的前序遍历
# 头节点相同,而且A的左子树包含了B的左子树,A的右子树包含了B的右子树
return A.val == B.val and dfs(A.left, B.left) and dfs(A.right, B.right)
再写一个函数,遍历A的所有节点
def isSubStructure(A: TreeNode, B: TreeNode) -> bool:
# 这里实现题目说的「空树不是任何树的子树」
if B is None:
return False
if A is None:
return False
# 三种情况:要么AB是头节点直接相等的覆盖关系,要么A的左子树覆盖B,要么A的右子树覆盖B,否则肯定不是覆盖关系
return dfs(A, B) or isSubStructure(A.left, B) or isSubStructure(A.right, B)
代码理解
为什么函数dfs里:
if B is None:
return True
而函数isSubStructure里:
if B is None:
return False
呢?
想想B什么时候为空是可以的,什么时候是不可以的?
按照题目的意思「空树不是任何树的子树」,如果一开始输入进来的B就是空的,那肯定要直接返回False的,这一步逻辑是在主函数isSubStructure实现的。
那么随着一层层的递归,传入给dfs的函数可能是B的某一个子树,如果此时这个子树为空了,是没问题的呀,说明你已经把B遍历完了嘛,这个时候当然返回True了。