基础版本



下标换算用具体例子来算
注意要判断越界情况, 因为如果根节点没有左树的话
比如这个,前序2、3、4
中序2、3、4
findIndex = L2
那么L1 + findIndex - L2 = L1
而左边界是L1+1了,就无效范围了
public TreeNode buildTree(int[] preorder, int[] inorder) {return f(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);}public TreeNode f(int[] pre, int L1, int R1, int[] in, int L2, int R2) {if (L1 > R1) {return null;}if (L1 == R1) {return new TreeNode(pre[L1]);}TreeNode head = new TreeNode(pre[L1]);int findIndex = 0;for (; findIndex < R2; findIndex++) {if (in[findIndex] == pre[L1]) {break;}}head.left = f(pre, L1 + 1, L1 + findIndex - L2, in, L2, findIndex - 1);head.right = f(pre, L1 + findIndex - L2 + 1, R1, in, findIndex + 1, R2);return head;}
优化版本
上面那个for循环是可以用一张map代替掉的, 记录in中每个值出现的位置
public TreeNode buildTree2(int[] preorder, int[] inorder) {HashMap<Integer, Integer> map = new HashMap<>();for (int i = 0; i < inorder.length; i++) {map.put(inorder[i], i);}return f2(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1, map);}public TreeNode f2(int[] pre, int L1, int R1, int[] in, int L2, int R2, HashMap<Integer, Integer> map) {if (L1 > R1) {return null;}if (L1 == R1) {return new TreeNode(pre[L1]);}TreeNode head = new TreeNode(pre[L1]);int findIndex = map.get(pre[L1]);head.left = f2(pre, L1 + 1, L1 + findIndex - L2, in, L2, findIndex - 1, map);head.right = f2(pre, L1 + findIndex - L2 + 1, R1, in, findIndex + 1, R2, map);return head;}
时间复杂度O(N)
因为找头现在是O(1)的,然后每调一次f函数搞定一个头,所以总的就是O(N)
