题目链接
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
pre:
1 | 2 | 4 | 7 | 3 | 5 | 6 | 8 |
---|
in:
4 | 7 | 2 | 1 | 5 | 3 | 8 | 6 |
---|
我们知道,前序遍历的第一个元素是二叉树的根,而且该元素将中序遍历序列分成的左右两部分分别是该元素的左右子树。根据此特性,我们可以递归构建二叉树。
比如上述序列中,前序序列的第一个元素为二叉树的根,中序序列中,元素 1 左边的元素(即 4,7,2)为其左子树的元素,元素 1 右边的元素(即5,3,8,6)为其右子树的元素,且中序遍历中 1 的 后三个元素正好是左子树元素,并且 1 的下一个元素 2 是其直接左孩子。剩下的都是 1 的右子树元素
左子树:
2 | 4 | 7 |
---|
右子树:
3 | 5 | 6 | 8 |
---|
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre, int [] in) {
if (pre.length == 0 || in.length == 0)
return null;
return reConstructBinaryTree(pre, in, 0, pre.length - 1, 0, in.length - 1);
}
// 返回 以 preL 为根的子树
private TreeNode reConstructBinaryTree(int[] pre, int[] in, int preL, int preR, int inL, int inR ) {
if (preL > preR)
return null;
TreeNode node = new TreeNode(pre[preL]);
int i = inL;
// 找到中序遍历序列中 pre[pre[L]]的位置
for (; i <= inR; i++) {
if (in[i] == pre[preL])
break;
}
int leftSize = i - inL; // 左子树元素 个数
node.left = reConstructBinaryTree(pre, in, preL + 1, preL + leftSize, inL , i - 1);
node.right = reConstructBinaryTree(pre, in, preL + leftSize + 1, preR, i + 1, inR);
return node;
}
}