输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
给定数组:
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回以下:3 / \ 9 20 / \ 15 7
前序遍历:根、左、右,所以数组第一个数肯定是根节点;
中序遍历:左、右、根,所以可以得出根节点的左边一定是左子树,右边为右子树。
根据这两个条件我们就可以得出根节点以及左右子树部分。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
Map<Integer, Integer> map;
public TreeNode buildTree(int[] preorder, int[] inorder) {
map = new HashMap<>();
int n = inorder.length;
for(int i=0;i<n;i++) {
map.put(inorder[i], i);
}
return reBuild(preorder, inorder, 0, n-1, 0, n-1);
}
private TreeNode reBuild(int[] preorder, int[] inorder, int pre_l, int pre_r, int in_l, int in_r) {
if(pre_l > pre_r) return null;
int pre_root = pre_l;
//前序数组第一个数一定是根节点
int in_root = map.get(preorder[pre_root]);
//找出中序数组根节点的位置,就可以得出左右子树数据的个数了,然后递归左右部分重建二叉树
int l_num = in_root - in_l;
TreeNode root = new TreeNode(preorder[pre_root]);
root.left = reBuild(preorder, inorder, pre_l + 1, pre_l + l_num, in_l, in_root - 1);
root.right = reBuild(preorder, inorder, pre_l + l_num + 1, pre_r, in_root + 1, in_r);
return root;
}
}