leetcode(10)二叉树子树、子结构系列题目
注意:如果当前节点会对下面的子节点有整体影响,可以通过辅助函数增长参数列表,借助参数传递信息。
子树题目
101. 对称二叉树
注意:只能是“后序遍历”,因为我们要通过递归函数的返回值来判断两个子树的内侧节点和外侧节点是否相等。
正是因为要遍历两棵树而且要比较内侧和外侧节点,所以准确的来说是一个树的遍历顺序是左右中,一个树的遍历顺序是右左中。
#递归
class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
if not root:
return True
return self.compare(root.left, root.right)
def compare(self, left, right):
#首先排除空节点的情况
if left == None and right == None:
return True
# elif left == None and right !=None:
# return False
# elif left != None and right == None:
# return False
elif left == None or right == None:
return False
#排除了空节点,再排除数值不相同的情况
elif left.val != right.val:
return False
#此时就是:左右节点都不为空,且数值相同的情况
#此时才做递归,做下一层的判断
outside = self.compare(left.left, right.right) #左子树:左、 右子树:右
inside = self.compare(left.right, right.left) #左子树:右、 右子树:左
isSym = inside and outside #左子树:中、 右子树:中 (逻辑处理)
return isSym
100. 相同的树
判断两个树是否相等的三个条件是与的关系,即:
- 当前两个树的根节点值相等;
- 并且,s 的左子树和 t 的左子树相等;
- 并且,s 的右子树和 t 的右子树相等。
#递归
class Solution:
def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
if not p and not q:
return True
elif not p or not q or p.val != q.val:
return False
left = self.isSameTree(p.left, q.left)
right = self.isSameTree(p.right, q.right)
# 注意是与
return left and right
572. 另一棵树的子树
面试题 04.10. 检查子树
而判断 t 是否为 s 的子树的三个条件是或的关系,即:
- 当前两棵树相等;
- 或者,t 是 s 的左子树;
- 或者,t 是 s 的右子树。
class Solution:
def isSubtree(self, root: TreeNode, subRoot: TreeNode) -> bool:
if not root or not subRoot:
return False
# 注意是或
return self.compare(root, subRoot) or self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot)
def compare(self, root, subRoot):
if not root and not subRoot:
return True
elif not root or not subRoot or root.val != subRoot.val:
return False
return self.compare(root.left, subRoot.left) and self.compare(root.right, subRoot.right)
剑指 Offer 27. 二叉树的镜像
class Solution:
def mirrorTree(self, root: TreeNode) -> TreeNode:
if not root:
return root
left = self.mirrorTree(root.left)
right = self.mirrorTree(root.right)
root.left, root.right = right, left
return root
子结构题目
子树和子结构的区别是:
子树要求
if not root and not subRoot: #只有AB同时为空才是true
return True
而子结构只要
if not B: # 判断子结构到叶节点处时,不要求A也到叶子节点
return True
即从某个节点到达叶子节点都一样才算子树,例如下面是子结构但不是子树:
剑指 Offer 26. 树的子结构
class Solution:
def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool:
if not A or not B:
return False
return self.compare(A, B) or self.isSubStructure(A.left, B) or self.isSubStructure(A.right, B)
def compare(self, A, B):
if not B: # 判断子结构到叶节点处时,不要求A也到叶子节点
return True
elif not A or A.val != B.val:
return False
return self.compare(A.left, B.left) and self.compare(A.right, B.right)
1367. 二叉树中的列表
class Solution:
def isSubPath(self, head: ListNode, root: TreeNode) -> bool:
if not head or not root:
return False
return self.compare(head, root) or self.isSubPath(head, root.left) or self.isSubPath(head, root.right)
def compare(self, head, root):
if not head:
return True
elif not root or head.val != root.val:
return False
return self.compare(head.next, root.left) or self.compare(head.next, root.right)