题目地址:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
难度:中等
思路:
首先需要了解前序和中序的定义:
- 前序序列即:根 -> 左 -> 右
- 中序序列即:左 -> 根 -> 右
因此,可以通过前序序列得知要构造的二叉树的根节点即其第一个节点, 而如果在给定的中序序列数组中找到这个根节点,就可以确定其左右子树的分界点。
public class Soultion {public TreeNode buildTree(int[] preorder, int inorder) {// 保存给定的前序和中序数组长度int preLen = preorder.length;int inLen = inorder.length;// 异常检查(可选操作)if(preLen != inLen) {throw new RuntimeException("Incorrect input data");}Map<Integer, Integer> map = new HashMap<>();for(int i = 0; i < preLen; i++) {map.put(inorder[i], i);}return buildTreeHelper(preorder, 0, preLen - 1, map, 0, inLen - 1);}private TreeNode buildTreeHelper(int[] preorder, int preLeft, int preRight, Map<Integer, Integer> map, int inLeft, int inRight) {// 递归函数的终止条件if (preLeft > preRight || inLeft > inRight) {return null;}// 根据前序遍历获取根节点的值int rootVal = preorder[preLeft];TreeNode root = new TreeNode(rootVal);// 中序遍历中,根节点的下标int pIndex = map.get(rootVal);root.left = buildTreeHelper(preorder, preLeft + 1, pIndex - inLeft + preLeft, map, inLeft, pIndex - 1);root.right = buildTreeHelper(preorder, pIndex - inLeft + preLeft + 1, preRight, map, pIndex + 1, inRight);return root;}}
