TreeNode buildTreeWithPreorderAndInorder(int[] preorder, int[] inorder,
			int startPreOrder, int endPreOrder, int startInOrder, int endInOrder) {
		// if startPreOrder out of range of preorder
		if (startPreOrder >= preorder.length)
			return null;
		TreeNode root = new TreeNode(preorder[startPreOrder]);

		int indexRootInOrder = startInOrder;

		// find root in inorder
		while (inorder[indexRootInOrder] != preorder[startPreOrder]
				&& indexRootInOrder <= endInOrder) {
			indexRootInOrder++;
		}

		int distance = indexRootInOrder - startInOrder;
		if (indexRootInOrder > startInOrder) {
			root.left = buildTreeWithPreorderAndInorder(preorder, inorder,
					startPreOrder + 1, startPreOrder + distance, startInOrder,
					indexRootInOrder - 1);
		}
		if (indexRootInOrder < endInOrder) {
			root.right = buildTreeWithPreorderAndInorder(preorder, inorder,
					startPreOrder + distance + 1, endPreOrder,
					indexRootInOrder + 1, endInOrder);
		}

		return root;
	}