题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
输入输出
输入
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
限制:0 <= 节点个数 <= 5000
解题思路
前序遍历特点:节点按照[根节点|左子树|右子树]排序,
如上例:pre[]=[3|9|20,15,7]
中序遍历特点:节点按照[左子树|根节点|右子树]排序,
如上例:in[]=[9|3|15,20,7]
递归步骤:
- 取前序遍历数组首元素pre[0]=3,该首元素为根节点;
- 在中序遍历数组 in[ ] 中找到根节点3的下标 i ,根据中序遍历[左|根|右]的特性,下标[0,i-1]范围对应根节点3的左子树节点;下标[i+1,in.length-1]范围对应根节点3的右子树节点;
- 由步骤 2 知左子树节点数目为 i,根据前序遍历[根|左|右]的特性,当pre[0]为根节点时,其左子树节点对应下标为[1,i],其右子树节点对应下标为[i+1,pre.length-1]。
- 递归进行上述1,2,3的步骤。每次递归需要截取此时的前序遍历与中序遍历数组。
图解递归树
对于上例输入,递归树如下:
根据递归树得到重建的二叉树:
代码
Java版本:递归法
import java.util.*;
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if(pre.length==0||in.length==0){
return null;
}
TreeNode root=new TreeNode(pre[0]);
for(int i=0;i<in.length;i++){
if(in[i]==pre[0]){
root.left=reConstructBinaryTree(
Arrays.copyOfRange(pre,1,i+1),
Arrays.copyOfRange(in,0,i));
root.right=reConstructBinaryTree(
Arrays.copyOfRange(pre,i+1,pre.length),
Arrays.copyOfRange(in,i+1,in.length));
}
}
return root;
}
}
注意:
java中java.util.Arrays下的函数:
public static int[] copyOfRange(int[] original,int from, int to)
功能:拷贝原数组original的区间[from,to)内的元素,返回拷贝后的数组。注意拷贝区间左闭右开。
力扣地址:剑指 Offer 07. 重建二叉树