树用递归比较多,每次都要选择left子树、right子树,所以用循环不太方便,直接递归选择子树作为当前树来进行处理。
前序、中序、后序遍历
直接看链接。
前序:根、左、右递归
中序:左、根、右递归
后续:左、右、根递归
分析:
前序的第一个元素必定是根节点,那么中序整体结构是左根右,
所以前序的第一个元素在中序中的位置的左边为左子树,右边为右子树。
首先整体前、中序看做一个树进行处理,然后找到左、右子树后,再递归对左、右子树进行处理。
那么递归结束的条件?前/中序序列中没有剩余数据了即返回None。
边界条件也进行判断一下?序列为空则返回None。
递归函数的作用从整体和局部两个方面分三步走:
1.整体:确定当前root节点,然后root的left和right想要被确定函数就必须要返回一个东西。
2.局部:假设现在是子树,root节点被确定后,该root节点的left和right被确定可以先不理会,那么整个函数返回的应该是该子树的root节点。
3.整体+局部:先确定最终的root节点,然后root.left得到的就是左子树返回的‘root’,root.right同理,最后返回最终的root即可。
递归的三套路和DP一样,也是找到函数作用,找到关联处,找到停止条件。
直接上代码:
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回构造的TreeNode根节点
def reConstructBinaryTree(self, pre, tin):
# write code here
if len(pre) == 0:
return None
root = TreeNode(pre[0])
mid = tin.index(pre[0])
root.left = self.reConstructBinaryTree(pre[1:mid+1], tin[:mid])
root.right = self.reConstructBinaryTree(pre[mid+1:], tin[mid+1:])
return root
分析:
复杂问题分解为几个简单的问题。
A树大一点,B树小一点,将B树拿着在A树里找,有匹配到的,则B是A的子结构。
那么可以拆分为两个问题,一个问题是将B树与A树中的每个子树进行判断是否子结构,另一个问题是如何进行判断是否是子结构。注意第二个问题是A子树和B树均从根节点开始一步步进行判断。
1.那么我们先考虑A子树和B树从根节点进行判断的方法:
先判断根节点,然后判断左子树,再判断右子树,那么用循环不好表示左、右子树,所以还是用递归去实现。
def isSubtree(self, roota, rootb):
if rootb is None: # B树都结束了,但A树还有,那么B是A的子结构
return True
if roota is None: # A提前结束了,肯定不是子结构了。
return False
if roota.val != rootb.val:
return False
left = isSubtree(roota.left, rootb.left)
if left is False:
return False
right = isSubtree(roota.right, rootb.right)
if right is False:
return False
return True
2.再考虑将B树与A树中的每个子树进行判断是否子结构:
同样用到递归。
# -*- 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 pRoot1 is None:
return False
if pRoot2 is None:
return False
if self.isSubtree(pRoot1, pRoot2):
return True
left = self.HasSubtree(pRoot1.left, pRoot2)
# 注意这里千万不要写成isSubtree函数!!!
if left is True:
# 注意这里的True判断,如果为False,
# 那么则继续向下判断,而不是return False!!!
# 所以这里是判断True!
return True
right = self.HasSubtree(pRoot1.right, pRoot2)
if right is True:
return True
#return False
def isSubtree(self, roota, rootb): # 该部分注释参考上面写好的注释
if rootb is None:
return True
if roota is None:
return False
if roota.val != rootb.val:
return False
left = self.isSubtree(roota.left, rootb.left)
if left is False:
return False
right = self.isSubtree(roota.right, rootb.right)
if right is False:
return False
return True