/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        int len = inorder.length;
        return buildSubtree(inorder, 0, len - 1, postorder, 0, len - 1);
    }
    
    private TreeNode buildSubtree(int[] inorder, int lo1, int hi1, int[] postorder, int lo2, int hi2){
        if (lo1 > hi1)
            return null;
        TreeNode node = new TreeNode(postorder[hi2]);
        int index = find(inorder,postorder[hi2], lo1, hi1);
        int leftLen = index - lo1;
        int rightLen = hi1 - index;
        node.left = buildSubtree(inorder, lo1, index - 1, postorder, lo2, lo2 + leftLen - 1);
        node.right = buildSubtree(inorder, index + 1, hi1, postorder, hi2 - rightLen, hi2 - 1);
        return node;
    }
    
    private int find(int[] inorder, int target, int lo, int hi){
        for (int i = lo; i <= hi; i++){
            if (inorder[i] == target)
                return i;
        }
        return -1;
    }
}