题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
代码示例
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Offer6 {
private List<Integer> res = new ArrayList<>();
public static void main(String[] args) {
int[] pre = {1,2,4,7,3,5,6,8};
int[] in = {4,7,2,1,5,3,8,6};
Offer6 testObj = new Offer6();
TreeNode root = testObj.reBuildBinaryTree(pre, in);
//用先序遍历验证重建的二叉树是否准确
testObj.preOrder(root);
System.out.println(testObj.res);
}
static class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int val) {
this.val = val;
}
}
//建立中序遍历序列数值和索引的映射关系
private Map<Integer, Integer> indexForInorders = new HashMap<>();
//根据先序遍历序列和中序遍历序列重建二叉树
public TreeNode reBuildBinaryTree(int[] pre, int[] in) {
for (int i = 0; i < in.length; i++) {
indexForInorders.put(in[i], i);
}
return reBuildBinaryTree(pre, 0, pre.length - 1, 0);
}
//先处理根节点,然后再递归处理左子树和右子树
private TreeNode reBuildBinaryTree(int[] pre, int preLeft, int preRight, int inLeft) {
if (preLeft > preRight) {
return null;
}
TreeNode root = new TreeNode(pre[preLeft]);//先序遍历第一个结点为root结点
int inIndex = indexForInorders.get(root.val);//找到中序遍历序列的root结点索引将其分割成左右子树
int leftTreeSize = inIndex - inLeft;//左子树的个数
root.left = reBuildBinaryTree(pre, preLeft + 1, preLeft + leftTreeSize, inLeft);
root.right = reBuildBinaryTree(pre, preLeft + leftTreeSize + 1, preRight, inLeft + leftTreeSize + 1);
return root;
}
//先序遍历二叉树,递归实现
private void preOrder(TreeNode root) {
if (root == null) {
return;
}
res.add(root.val);
preOrder(root.left);
preOrder(root.right);
}
}