递归, 分治

跟精华解法一样思路,通过preOrder找root,inOrder找左右subtree的size.
唯一不一样的就是用HashMap存inOrder的[val -> index]。这样跑起来快很多。
时间 O(n): 每个node都会call一次build()
空间 O(n): 系统栈上worst-case最多n个node,hashMap也是O(n)

import java.util.*;

public class Solution {
    // val -> idx in vin
    Map<Integer, Integer> vinMap = new HashMap<>();
    // 存个global 省点笔墨
    int[] _pre, _vin;
  
    public TreeNode reConstructBinaryTree(int[] pre, int[] vin) {
      if (pre.length == 0) return null;
      _pre = pre; _vin = vin;
      
      // 将vin的val:idx存入HashMap方便O(1)查找
      for (int i=0; i < vin.length; i++) {
        vinMap.put(vin[i], i);
      }
      return build(0, pre.length-1, 0, vin.length-1);
    }
  
    // Build the tree represented by pre[preS, preE] and vin[inS, inE]
    TreeNode build(int preS, int preE, int inS, int inE) {
      // 每次分治的subtree的root就是pre[PreS]
      TreeNode root = new TreeNode(_pre[preS]);
      // basecase
      if (preS == preE) return root;
      
      // 找到root所对应的vin的idx,目的是求出left和right的subtree size
      int rootVinIdex = vinMap.get(_pre[preS]);
      int leftSize = rootVinIdex - inS;
      int rightSize = inE - rootVinIdex;
      
      // 这里必须check 不然空的一边会越界。放basecase里check也行
      if (leftSize > 0)
        root.left = build(preS+1, preS + leftSize, inS, rootVinIdex-1);
      if (rightSize > 0)
        root.right = build(preS + leftSize + 1, preE, rootVinIdex+1, inE);
      return root;
    }
}