108 - Convert Sorted Array to Binary Search Tree
Difficulty: Easy | Pattern: Divide and Conquer / Recursion | Company tags: Amazon, Airbnb, Microsoft
Problem Statement
Given an integer array nums where the elements are sorted in ascending order, convert it to a height-balanced binary search tree.
A height-balanced binary tree is one in which the depth of the two subtrees of every node never differs by more than one.
Example:
Input: nums = [-10,-3,0,5,9]
Output: [0,-3,9,-10,null,5]
0
/ \
-3 9
/ /
-10 5
Approach: Divide and Conquer — O(n)
Key insight: The middle element of a sorted array is the root of a height-balanced BST. Recursively apply this to left half (left subtree) and right half (right subtree).
Algorithm Flow
def sortedArrayToBST(nums: list[int]):
if not nums:
return None
mid = len(nums) // 2
root = TreeNode(nums[mid])
root.left = sortedArrayToBST(nums[:mid])
root.right = sortedArrayToBST(nums[mid+1:])
return root
Optimized: Index-Based (Avoid Array Slicing)
def sortedArrayToBST(nums: list[int]):
def helper(left, right):
if left > right:
return None
mid = (left + right) // 2
node = TreeNode(nums[mid])
node.left = helper(left, mid - 1)
node.right = helper(mid + 1, right)
return node
return helper(0, len(nums) - 1)
Dry Run
nums = [-10,-3,0,5,9]
| Call | Range | mid | Node | Left | Right |
|---|---|---|---|---|---|
| helper(0,4) | full | 2 | 0 | (-10,-3) | (5,9) |
| helper(0,1) | [-10,-3] | 0 | -10 | () | (-3) |
| helper(1,1) | [-3] | 1 | -3 | () | () |
| helper(3,4) | [5,9] | 3 | 5 | () | (9) |
| helper(4,4) | [9] | 4 | 9 | () | () |
Result BST (by level order): [0,-10,5,null,-3,null,9] ✓
Why Middle = Height Balanced
Choosing the middle index ensures each subtree gets floor(n/2) or ceil(n/2) nodes — a difference of at most 1. This directly satisfies the height-balance property.
Edge Cases
- Empty array → return None
- Single element → leaf node
- Two elements → root + one child (left or right depending on which is mid)
Complexity
- Time: O(n) — every element becomes a node exactly once
- Space: O(log n) — recursion depth of balanced tree
Key Terms
| Term | Definition |
|---|---|
| Height-balanced tree | A tree where every node's two subtrees differ in depth by at most 1. |
| Binary search tree invariant | For every node, all left-subtree values are smaller and all right-subtree values are larger. |
| Divide and conquer | Splitting a problem into independent subproblems (left/right halves) solved recursively. |
| Index-based recursion | Passing left/right bounds instead of slicing arrays, avoiding O(n) copy overhead per call. |
| Recursion depth | The maximum number of nested calls, here O(log n) because the array is halved each level. |
FAQ
Q: Can this be solved without extra space (beyond the output tree)? A: The index-based version uses only O(log n) auxiliary space for the recursion stack, no extra arrays — the slicing version uses O(n log n) extra space due to repeated array copies.
Q: What if the input array is empty?
A: sortedArrayToBST([]) returns None immediately, representing an empty tree — handled by the left > right (or not nums) base case.
Q: What if duplicate values are allowed in the array?
A: The algorithm still works structurally, but the BST invariant (left < node <= right or similar strict rule) must be defined consistently, since standard BSTs typically assume unique keys.
Q: Is the resulting BST unique? A: No — when the subarray length is even, choosing the lower-middle vs upper-middle index produces a different but equally valid height-balanced BST.
Q: What is the time complexity trade-off vs building an unbalanced BST via sequential inserts? A: Sequential inserts of sorted data into a naive BST produce a degenerate O(n) height (essentially a linked list); this divide-and-conquer approach guarantees O(log n) height and O(n) total construction time.
Quick Revision
- Goal: build a height-balanced BST from a sorted array.
- Key idea: the middle element becomes the root — it has equal (or near-equal) elements on both sides.
- Recurse on the left half for the left subtree, right half for the right subtree.
- Base case: empty range (
left > rightor empty slice) returnsNone. - Prefer index-based
helper(left, right)over array slicing to avoid extra copies. - Choosing the middle guarantees each subtree gets
floor(n/2)orceil(n/2)nodes, satisfying height-balance. - Time: O(n) — every element visited once.
- Space: O(log n) recursion stack (index-based) or O(n log n) (slicing version).
- Reverse-engineer: an in-order traversal of the result always reproduces the original sorted array.
Related Problems
- 98 - Validate Binary Search Tree — same BST invariant, checked instead of constructed
- 94 - Binary Tree Inorder Traversal — inorder traversal is the inverse operation of this problem
- Convert Sorted List to Binary Search Tree (LeetCode 109) — same pattern applied to a linked list instead of an array (no file in this set)