1.题目
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2.解法
2.1自顶向下递归
思路
- 自顶向下递归地构造二叉树,每次构造一个根节点
- 根据先序遍历特点,区间最左侧元素为根节点
- 根据中序遍历特点,根节点左侧为左子树、右侧为右子树
核心步骤:
- 先构造根节点
- 使用先序、中序数组中左子树区间,递归地构造左子树
- 使用先序、中序数组中右子树区间,递归地构造右子树
- 最后返回根节点
代码
public TreeNode buildTree(int[] preorder, int[] inorder) {
// preL,preR,inL,inR区间皆为闭区间
return buildTreeCore(preorder, 0, preorder.length-1, inorder, 0, inorder.length-1);
}
public TreeNode buildTreeCore(int[] preorder, int preL, int preR, int[] inorder, int inL, int inR){
// 区间中没有元素则返回
if(preL>preR||inL>inR){
return null;
}
// 构造根节点
TreeNode root = new TreeNode(preorder[preL]);
// 根据先序遍历,得知根节点,找到根节点对应于中序遍历的位置
for(int i=inL; i<=inR; i++){
if(inorder[i]==preorder[preL]){
root.left = buildTreeCore(preorder, preL+1, preL+i-inL, inorder, inL, i-1);
root.right = buildTreeCore(preorder, preL+i-inL+1, preR, inorder, i+1, inR);
break;
}
}
return root;
}