【LeetCode】面试题26. 树的子结构
题目:
思路:
这个问题可以拆分成
- 以A的根结点开始能否匹配 or A的左子树是否匹配 or A的右子树是否匹配(这个过程可以看作是找和B的根结点匹配节点的过程)
- A的左/右子树是否匹配,和上面的问题相同,递归处理
- 但是判断以A的根结点开始能否匹配,和上面的问题不同。因为已经找到根结点了,就不能中断和根结点的连接
- 如果根结点匹配后,再去递归处理A的左/右子树是否和B的左/右子树匹配,是错误的。
- 找到根结点后,就不是和主问题相同的寻找子树问题了。而是判断两个树从当前根结点开始是否匹配。
- 比如[1,0,1,-4,-3]和[1,-4]不是子结构,但是如果判断完1后再去判断[0,1,-4,-3]和[-4]是否为子结构得到的结果是错误的。
- 所以这个问题可以划分为递归寻找匹配的根结点,找到后判断两个树是否匹配。
- 判断两个树是否匹配就是树的遍历,可以广度优先(层次遍历)、也可以深度优先
代码:
Python
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def isSubStructure(self, A, B):
"""
:type A: TreeNode
:type B: TreeNode
:rtype: bool
"""
# 只有第一次存在B为None的情况,因为之后B不会变
if A is None or B is None:
return False
# 利用队列BFS(层次遍历)判断两个树是否匹配
aQueue = [A]
bQueue = [B]
flag = True
while aQueue:
a = aQueue.pop()
b = bQueue.pop()
if b:
if a and a.val == b.val:
aQueue.append(a.left)
aQueue.append(a.right)
bQueue.append(b.left)
bQueue.append(b.right)
else:
flag = False
# 当前根结点是否匹配 or 左子树是否匹配 or 右子树是否匹配
return flag or self.isSubStructure(A.left, B) or self.isSubStructure(A.right, B)
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
# 利用递归实现DFS
def isMatch(self, A, B):
if B is None:
return True
if A is None or A.val != B.val:
return False
return self.isMatch(A.left, B.left) and self.isMatch(A.right, B.right)
def isSubStructure(self, A, B):
"""
:type A: TreeNode
:type B: TreeNode
:rtype: bool
"""
if A is None or B is None:
return False
return self.isMatch(A, B) or self.isSubStructure(A.left, B) or self.isSubStructure(A.right, B)