File: convert-sorted-array-to-binary-search-tree/solution.py

Date: 2026-06-06

Time: 15:53

Purpose

This file is a self-contained LeetCode solution for problem 108: Convert Sorted Array to Binary Search Tree. It owns three things: the TreeNode data structure, the sortedarrayto_bst algorithm, and a test suite that validates correctness via structural invariants (BST property, balance, in-order reconstruction).

Key Components

TreeNode

A standard binary tree node with val, left, and right. Uses PEP 604 union syntax (TreeNode | None) enabled by from _future_ import annotations. This class is the shared tree node definition across the entire repo — the "Imported By" list shows hundreds of other problem test files depend on it.

sortedarrayto_bst(nums) -> TreeNode | None

The main algorithm. Takes a sorted integer list and returns the root of a height-balanced BST. Delegates to a closure helper(left, right) that operates on index bounds rather than array slices.

helper(left, right) -> TreeNode | None

The recursive workhorse. Picks the middle index (left + right) // 2 as the root, then recurses on the left and right halves. The node construction is a single expression — TreeNode(nums[mid], helper(left, mid - 1), helper(mid + 1, right)) — so left and right subtrees are built before the parent node's constructor returns.

TestSortedArrayToBST

Tests don't assert a specific tree shape. Instead, assertvalid checks three structural properties: BST ordering, height-balance (no subtree pair differs by more than 1), and in-order traversal reproducing the original sorted input. This makes the tests robust to any valid balanced BST construction (e.g., choosing upper-mid vs lower-mid).

Patterns

Divide-and-conquer via index bounds. The closure captures nums and operates on (left, right) indices instead of creating sublists. This avoids O(n log n) total copying that slicing would incur, keeping space to O(log n) stack frames.

Invariant-based testing. Rather than hardcoding expected tree structures, tests verify the three defining properties of a correct answer. This is a pattern seen across BST-related solutions in this repo.

Floor-division midpoint. (left + right) // 2 biases toward the left-middle element for even-length ranges. This produces a valid balanced BST but not the only valid one — choosing (left + right + 1) // 2 would also be correct.

Dependencies

Imports: Only _future_.annotations (for X | None syntax in Python <3.10) and unittest. No external dependencies.

Imported by: This file's TreeNode class is imported by ~300+ test files across the repo. It serves as the canonical tree node definition for every binary tree problem in the collection.

Flow

1. sortedarrayto_bst([−10, −3, 0, 5, 9]) calls helper(0, 4).

2. helper computes mid = 2, picks nums[2] = 0 as root.

3. Left subtree: helper(0, 1)mid = 0, root −10, right child helper(1, 1) → leaf −3.

4. Right subtree: helper(3, 4)mid = 3, root 5, right child helper(4, 4) → leaf 9.

5. Result: a balanced BST with root 0, depth 3.

The recursion bottoms out when left > right, returning None (empty subtree).

Invariants

Error Handling

None. The function assumes valid input (a sorted list of integers). Empty lists are handled gracefully by the base case. No exceptions are raised or caught. The test suite relies on unittest assertions for failure reporting.

Topics to Explore

Beliefs