题目描述:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
先序、中序、后序说的都是根节点的位置。
先序遍历特点:第一个值是根节点
中序遍历特点:根节点左边都是左子树,右边都是右子树
思路:
1.首先根据先序遍历得到的根节点a,将中序遍历划分为两部分,左边为左子树,右边为右子树
2.在左子树中根据第一条规则递归,得出左子树
在右子树中根据第一条规则递归,得出右子树
3.由递归返回得到合成一棵树
注意:
递归元素有六个,包含两个数组和四个前后指针。递归的时候,左右子树对应的数组是这样划分的:
比如,输入前序遍历序列{1,2,4,7,3,5,6,8},中序遍历序列{4,7,2,1,5,3,8,6}。
前序根节点为1,在中序中找到1所在的位置;
中序前三个是左子数组元素,对应前序数组中除了首位之外的前面三个元素;
中序后三个是右子数组元素,对应前序数组中的最后三个元素。
具体代码如下:
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
return reConBTree(pre,0,pre.length-1,in,0,in.length-1);
}
public TreeNode reConBTree(int [] pre,int preleft,int preright,int [] in,int inleft,int inright){
if(preleft > preright || inleft> inright){return null;}//当到达边界条件时候返回null,也就是给了叶子节点以空孩子的形式
TreeNode pRootOfTree = new TreeNode(pre[preleft]);//新建一个TreeNode根节点
//对中序数组进行输入边界的遍历
for(int i = inleft; i<= inright; i++){
if(pre[preleft] == in[i]){
//重构左节点,注意边界条件
pRootOfTree.left = reConBTree(pre,preleft+1,preleft+i-inleft,in,inleft,i-1);
//重构右节点,注意边界条件
pRootOfTree.right = reConBTree(pre,preleft+i+1-inleft,preright,in,i+1,inright);
}
}
return pRootOfTree;
}
}