题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
二叉树:在计算机科学中,二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
- 前序遍历:前序遍历(DLR)也叫做先根遍历、先序遍历、前序周游,可记做 根->左->右 。前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。
- 中序遍历:中序遍历(LDR)也叫做中根遍历、中序周游。可记作 左->根->右 。中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树。
解题思路:
- 先求出根节点(前序序列第一个元素)。
- 将根节点带入到中序遍历序列中求出左右子树的中序遍历序列。
- 通过左右子树的中序序列元素集合带入前序遍历序列可以求出左右子树的前序序列。
- 左右子树的前序序列第一个元素分别是根节点的左右儿子
- 求出了左右子树的4种序列可以递归上述步骤
代码如下:
/**
* 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) {
if (pre == null || in == null) {
return null;
}
return construct(pre, 0, pre.length - 1, in, 0, in.length - 1);
}
public TreeNode construct(int[] pre, int p_start, int p_end, int[] in, int i_start, int i_end) {
if (p_start > p_end) return null;
int start = i_start;
while (start <= i_end && pre[p_start] != in[start]) {
start++;
}
TreeNode node = new TreeNode(pre[p_start]);
node.left = construct(pre, p_start + 1, p_start + start - i_start, in, i_start, start - 1);
node.right = construct(pre, p_start + start - i_start + 1, p_end, in, start + 1, i_end);
return node;
}
}