、
解题思路
假设已知先序序列为pre1、pre2、……、pren,中序序列为in1、in2、……、inn,如下图所示。
那么由先序序列的性质可知,先序序列的第一个元素pre1是当前二叉树的根节点。再由中序序列的性质可知,当前二叉树的根节点将中序序列划分为左子树和右子树。因此,要做的就是在中序序列中找到某个结点in k,使得in k==pre1,这样就在中序序列中找到了根节点。
易知左子树的结点个数numLeft=k-1。于是,左子树的先序序列区间就是[2,k],左子树的中序序列区间是[1,k-1];右子树的先序序列区间是[k+1,n],右子树的中序序列区间是[k+1,n],接着只需要往左子树和右子树进行递归构建二叉树即可。
事实上,如果递归过程中当前先序序列的区间为[preL,preR],中序序列的区间为[inL,inR],那么左子树的结点个数为numLeft=k-inL。这样左子树的先序序列区间就是[preL+1,preL+numLeft],左子树的中序序列区间是[inL,k-1];右子树的先序序列区间是[preL+numLeft+1,preR],右子树的中序序列区间是[k+1,inR]。
那么,如果一直这样递归下去,什么时候是尽头呢?这个问题的答案是显然的,因为只要先序序列的长度小于等于0时,当前二叉树就不存在了,于是就能以这个条件作为递归边界。
AC代码
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func buildTree(preorder []int, inorder []int) *TreeNode {
if len(preorder)==0{
return nil
}
root:=&TreeNode{Val:preorder[0]}
i:=0
for ;i<len(inorder);i++{
if inorder[i]==preorder[0]{
break
}
}
root.Left=buildTree(preorder[1:i+1],inorder[:i]) //左孩子i个
root.Right=buildTree(preorder[i+1:],inorder[i+1:])
return root
}
感悟
其实还是分而治之的思想,根据前序序列的根节点找到中序序列中根结点的左右孩子区间,当区间长度为0时就返回空指针。