题面
根据一棵树的中序遍历与后序遍历构造二叉树。假设树中没有重复的元素
中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]
返回二叉树
3
/ \
9 20
/ \
15 7
分析
- 中序遍历将二叉树分成左右两棵子树 (左 根 右)
- 后序遍历最后访问根结点 (左 右 根)
递归建树
hashbuild(inorder, postorder, 0 , n - 1, 0, n - 1) ,ninL > inRpL > pRkk(inL,k - 1), (k + 1, inR)(pL, pL + k - inL - 1), (pL + k - inL, pR -1)
实现
此法类似于刻舟求剑(hash数据一次成型),但无需要在递归时维护一个数组副本,亦不需要每次递归动态比对中序遍历索引
func buildTree(inorder []int, postorder []int) *TreeNode {
m :=make(map[int]int,len(inorder))
var bt func(int,int,int,int)*TreeNode
for i,v:=range inorder{
m[v]=i
}
bt=func(inL,inR,postL,postR int)*TreeNode{
if inL > inR || postL > postR {
return nil
}
k := m[postorder[postR]]
return &TreeNode{
Val:postorder[postR],
Left:bt(inL, k - 1, postL, postL + k - 1 - inL),
Right:bt(k + 1, inR, postL + k - inL, postR - 1),
}
}
return bt(0,len(inorder)-1,0,len(postorder)-1)
}
python版
递归动态查询各层,目标数根节点在当层中序中的索引,求索方便,但耗费空间比上述go高20倍
class Solution:
def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
if not postorder:
return None
root = TreeNode(postorder.pop())
index = inorder.index(root.val)
root.left = self.buildTree(inorder[:index],postorder[:index])
root.right = self.buildTree(inorder[index+1:],postorder[index:])
return root