//输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
//
//
//
// 例如,给出
//
// 前序遍历 preorder = [3,9,20,15,7]
//中序遍历 inorder = [9,3,15,20,7]
//
// 返回如下的二叉树:
//
// 3
// / \
// 9 20
// / \
// 15 7
//
//
//
// 限制:
//
// 0 <= 节点个数 <= 5000
//
//
//
// 注意:本题与主站 105 题重复:https://leetcode-cn.com/problems/construct-binary-tree-from-
//preorder-and-inorder-traversal/
// Related Topics 树 递归
// 👍 292 👎 0
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder.length <= 0 || inorder.length <= 0) {
return null;
}
return buildTreeCore(preorder, 0, preorder.length - 1,
inorder, 0, inorder.length - 1);
}
private TreeNode buildTreeCore(int[] preorder, int startPre, int endPre,
int[] inorder, int startMid, int endMid) {
/*if (startPre > endPre) {
return null;
}*/
if (startMid > endMid) {
return null;
}
TreeNode root = new TreeNode(preorder[startPre]);
// 确定左右子树的长度
int index = findRootIndexInMidTree(inorder, preorder[startPre]);
int leftLen = index - startMid;
int rightLen = endMid - index;
// 前序数组中:startPre + 1是左子树的起点;startPre + leftLen 是左子树的终点
// 中序数组中:index - leftLen 是左子树的起点,index -1 是左子树的终点
root.left = buildTreeCore(preorder, startPre + 1, startPre + leftLen,
inorder, index - leftLen, index - 1);
// 前序数组中:startPre + 1是左子树的起点;startPre + leftLen 是左子树的终点
// 中序数组中:index - leftLen 是左子树的起点,index -1 是左子树的终点
root.right = buildTreeCore(preorder, endPre - rightLen + 1, endPre,
inorder, index + 1, index + rightLen);
return root;
}
private int findRootIndexInMidTree(int[] inorder, int rootVal) {
for (int i = 0; i < inorder.length; i++) {
if (inorder[i] == rootVal) {
return i;
}
}
return -1;
}
}