唯一的难点就是确定当前节点的左子树的根节点和右子树的根节点分别在前序遍历数组的位置。例如
先序遍历数组pre:1 2 3 4 5 6 7
中序遍历数组in: 3 2 4 1 6 5 7
1是当前根节点,它在pre中的位置
pre_start = 0
接着在in中找到1的位置,即分割点
j = 3
当前树根所囊括的in数组范围是
in_start = 0;
in_end = in.length-1;
将in按j分割后,3 2 4就是其左子树部分,6 5 7就是其右子树部分。那么左子树和右子树的根节点是哪个呢?根节点是由先序遍历数组确定的。
在pre数组中,注意到,左子树的根节点就是当前根节点的下一个,即
root_left = pre_start + 1
而右子树的根节点需要在当前根节点pre_start的基础上向前移动j-in_start+1个位置,到达右子树的部分,这部分的第一个元素就是右子树的根节点了:
root_right = pre_start + j - in_start + 1
所以,代码如下:
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if (pre.length==0) return null;
return construct(pre, in, 0, 0, in.length-1);
}
private TreeNode construct(int[] pre, int[] in,
int pre_start,
int in_start, int in_end) {
if(in_start>in_end) return null;
if(in_start==in_end) return new TreeNode(pre[pre_start]);
TreeNode son = new TreeNode(pre[pre_start]);
int j = in_start;
while(in[j]!=pre[pre_start]) j++;
// Find the root respectively for left part and right part
son.left = construct(pre, in, pre_start+1, in_start, j-1);
son.right = construct(pre, in, pre_start+j-in_start+1, j+1, in_end);
return son;
}
}