1.本题知识点
二叉树,递归
2. 题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
3. 概念解析
① 什么是二叉树?
二叉树是每个结点最多有两个子树的树结构。二叉就是只有左右两条路径。
② 二叉树的遍历方式
有哪些?
深度优先搜索DFS:先序遍历、中序遍历、后序遍历。
广度优先搜索BFS:层序遍历。
4. 思路
整理思路:根据先序和中序序列来构建树及其左右子树。
★ 主要步骤分两点:
No.1 首先在先序序列中确定root节点,此时,树的根节点确定了。
No.2 在中序序列中寻找root节点,找到之后通过递归构造左右子树,此时,树的左右子树确定了。
No.3 综上,此时当前树的结构就构建好了。对于left和right子树用同样的方式构建即可(递归)。(对于二叉树,一般都是只同时考虑root、left、right)
关键点:为了确定数组中的左右子树,所以要计算先序和中序start和end索引值。那么如何计算呢?
① 中序的start和end索引值很好确定,肉眼看就可以。
② 先序的start end索引则根据中序确定的左子树长度来计算。
比如,计算左子树的索引,如下图,中序root索引为rootIndex = 3,左子树长度LeftLen = 3,则中序的左子树索引 0 ~ rootIndex-1,先序的左子树索引为 0 + (rootIndex - 0)(前序的start索引 + 中序中左子树的长度)。如果还不明白可看下图和代码。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/297a55e8a5c44d6fd2594b41b6d2f2d3.png)
Java版本:
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
TreeNode root=reConstructBinaryTree(pre,0,pre.length-1,in,0,in.length-1);
return root;
}
private TreeNode reConstructBinaryTree(int [] pre,int startPre,int endPre,
int [] mid,int startMid,int endMid)
{
if(startPre>endPre||startMid>endMid)
return null;
TreeNode root=new TreeNode(pre[startPre]);
for(int i = startMid;i <= endMid;i++)
{
if(mid[i] == pre[startPre]){
root.left=reConstructBinaryTree(pre,startPre+1,startPre+(i-startMid),mid,startMid,i-1);
root.right=reConstructBinaryTree(pre,startPre+(i-startMid)+1,endPre,mid,i+1,endMid);
break;
}
}
return root;
}
}