Convert Sorted Array to Height Balanced Binary Search Tree
A class Solution with only public members can be written struct Solution.  But with only a single member function (that never uses the this pointer), why not a free function?

Presumably your vector is intended to be a std::vector, in which case we need #include &lt;vector&gt; and the correct namespace qualifier.

Don't pass a reference to a mutable object unless it's reasonable for the function to modify it.  In this case, we just want to copy from it, so pass a const std::vector&lt;int&gt;&amp; instead.

You're right that it's very inefficient to make many new containers, when we just want a view; that's exactly what iterator-pairs (aka ranges) are good for.  I'll not consider the first version any further.

There's no need to accept only vectors of int - we'd like to accept any ordered random-access container, of any element type.  That's easy enough, with a template:

template&lt;typename RandomAccessIterator&gt;
TreeNode* makeBST(RandomAccessIterator start, RandomAccessIterator end){


There's a serious bug when new TreeNode() fails: all the allocated nodes further up the call tree will be leaked as the std::bad_alloc propagates upwards.  It's better to make the BST use smart pointers.  If you can't change that implementation, then we can achieve exception safety by holding each root in a smart pointer until after the potentially-throwing recursive calls:

    auto root = std::make_unique&lt;TreeNode&gt;(*mid);
    root-&gt;left = makeBST(start, mid);
    root-&gt;right = makeBST(mid + 1, end);
    return root.release();