基础版本

image.png

image.png
image.png

下标换算用具体例子来算
image.png

注意要判断越界情况, 因为如果根节点没有左树的话
image.png
比如这个,前序2、3、4
中序2、3、4
findIndex = L2
那么L1 + findIndex - L2 = L1
而左边界是L1+1了,就无效范围了
image.png

  1. public TreeNode buildTree(int[] preorder, int[] inorder) {
  2. return f(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
  3. }
  4. public TreeNode f(int[] pre, int L1, int R1, int[] in, int L2, int R2) {
  5. if (L1 > R1) {
  6. return null;
  7. }
  8. if (L1 == R1) {
  9. return new TreeNode(pre[L1]);
  10. }
  11. TreeNode head = new TreeNode(pre[L1]);
  12. int findIndex = 0;
  13. for (; findIndex < R2; findIndex++) {
  14. if (in[findIndex] == pre[L1]) {
  15. break;
  16. }
  17. }
  18. head.left = f(pre, L1 + 1, L1 + findIndex - L2, in, L2, findIndex - 1);
  19. head.right = f(pre, L1 + findIndex - L2 + 1, R1, in, findIndex + 1, R2);
  20. return head;
  21. }

优化版本

上面那个for循环是可以用一张map代替掉的, 记录in中每个值出现的位置

  1. public TreeNode buildTree2(int[] preorder, int[] inorder) {
  2. HashMap<Integer, Integer> map = new HashMap<>();
  3. for (int i = 0; i < inorder.length; i++) {
  4. map.put(inorder[i], i);
  5. }
  6. return f2(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1, map);
  7. }
  8. public TreeNode f2(int[] pre, int L1, int R1, int[] in, int L2, int R2, HashMap<Integer, Integer> map) {
  9. if (L1 > R1) {
  10. return null;
  11. }
  12. if (L1 == R1) {
  13. return new TreeNode(pre[L1]);
  14. }
  15. TreeNode head = new TreeNode(pre[L1]);
  16. int findIndex = map.get(pre[L1]);
  17. head.left = f2(pre, L1 + 1, L1 + findIndex - L2, in, L2, findIndex - 1, map);
  18. head.right = f2(pre, L1 + findIndex - L2 + 1, R1, in, findIndex + 1, R2, map);
  19. return head;
  20. }

时间复杂度O(N)

因为找头现在是O(1)的,然后每调一次f函数搞定一个头,所以总的就是O(N)