1. 题目描述
2.解题思路
题目分析:
- 前序遍历特点: 节点按照 [ 根节点 | 左子树 | 右子树 ] 排序,以题目示例为例:[ 3 | 9 | 20 15 7 ]
- 中序遍历特点: 节点按照 [ 左子树 | 根节点 | 右子树 ] 排序,以题目示例为例:[ 9 | 3 | 15 20 7 ]
- 根据题目描述输入的前序遍历和中序遍历的结果中都不含重复的数字,其表明树中每个节点值都是唯一的。
思路:
- 前序遍历的第一个数就是根节点root
- 在中序遍历中找到root对应的位置,可以求出root的左子树和右子树分别对应哪些节点
- 然后再对左右子树进行递归,每次递归可以确定三个节点的关系。
递归解析:
- 先根据前序遍历找到根节点对应的索引 pre_root
- 然后根据pre_root的值,在中序遍历中找到对应数的索引 index
- root = new TreeNode(po[pre_root]) ;
- root.left = 向左递归
- root.right = 向右递归
- 递归结束的条件是,in_left > in_right,返回null,说明下面没有节点了。
- 树构建的过程:一直向左递归,先构建最左边的三个节点的子树,然后返回上一层,再将该子树看作一个节点,继续完成三个“节点”子树的创建,知道递归调用结束,返回最开始的root,构建出一个完整的树。
3. 代码
class Solution {
HashMap<Integer,Integer> map = new HashMap();//装入的是中序遍历数组中,值对应的下标,方便查找,无需多次遍历中序数组
int[] po; //和前序遍历的数组一模一样
public TreeNode buildTree(int[] preorder, int[] inorder) {
po = preorder;
//初始化map
for(int i = 0; i < inorder.length; i++){
map.put(inorder[i],i);
}
return recur(0,0,inorder.length -1);
}
//递归函数,传入构建子树的根节点和左右边界
TreeNode recur(int pre_root, int in_left, int in_right){
if(in_left > in_right){
return null;
}
//根据索引获取值,构建根节点
TreeNode root = new TreeNode(po[pre_root]);
//找到该值对应的中序数组下标
int index = map.get(root.val);
//向左进行遍历
root.left = recur(pre_root + 1,in_left,index - 1);
root.right = recur(pre_root + index - in_left + 1,index + 1,in_right);
return root;
}
}
4. 测试结果