问题描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
输入描述:
输入两个数组,一个是二叉树的前序遍历,一个是二叉树的中序遍历
输出描述:
输出重建的二叉树
示例
示例1
输入
[1,2,4,7,3,5,6,8],[4,7,2,1,5,3,8,6]
输出
重建的二叉树,树的结构如下图
解决思路
分析
本题主要是需要先明确前序遍历和中序遍历的特点。
- 通过前序遍历,我们可以知道第一个节点是跟节点
- 通过前序遍历的根节点,和中序遍历,我们可以知道左子树和右子树的长度,以及将中序遍历拆分成, 左子树 - 根节点 - 右子树
- 根据长度前序遍历拆分开,可以得到,根节点 - 左子树 - 右子树
- 可以通过如下图理解这些特点:
方法
- 以前序遍历的首元素为跟节点。
- 在中序遍历中以跟节点为基准,将左右子树的拆分
- 通过长度拆分开前序遍历的左右子树和中序遍历的左右子树
- 递归即可
代码实现
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if (pre.length == 0 || in.length == 0) {
return null;
}
// 前序遍历的首个节点是根节点
TreeNode treeNode = new TreeNode(pre[0]);
// 遍历中序遍历查找根节点
for (int i = 0; i < in.length; i++){
// 找到匹配的根节点
if (pre[0] == in[i]) {
// 左子树递归,根据个数获取左子树的前序遍历,根据个数获取左子树的中序遍历(注意:这里的+1是剔除跟节点后的长度)
treeNode.left = reConstructBinaryTree(Arrays.copyOfRange(pre, 1, i + 1), Arrays.copyOfRange(in, 0, i));
// 右子树递归,根据个数获取右子树的前序遍历,根据个数获取右子树的中序遍历
treeNode.right = reConstructBinaryTree(Arrays.copyOfRange(pre, i + 1, pre.length), Arrays.copyOfRange(in, i + 1, in.length));
}
}
return treeNode;
}
}
小伙伴如果想测试的话,可以直接到牛客网这个链接做测试