To create a height-balanced BST from a sorted array, we need to ensure that for every node, the left and right subtrees have roughly equal heights. Since the array is sorted, the middle element should become the root. All elements before the middle go to the left subtree, and all elements after go to the right subtree. Applying this recursively builds a balanced tree.
null.# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
if not nums:
return None
mid = len(nums) // 2
root = TreeNode(nums[mid])
root.left = self.sortedArrayToBST(nums[:mid])
root.right = self.sortedArrayToBST(nums[mid + 1:])
return rootThe previous approach creates new array copies for each recursive call, which is inefficient. Instead, we can pass indices (left and right boundaries) to indicate the current segment of the array. This avoids array slicing and reduces both time and space overhead while maintaining the same logic of choosing the middle element as root.
left and right boundary indices.left > right, return null (empty segment).(left + right) / 2.(left, mid - 1).(mid + 1, right).(0, n - 1) and return the result.# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
def helper(l, r):
if l > r:
return None
m = (l + r) // 2
root = TreeNode(nums[m])
root.left = helper(l, m - 1)
root.right = helper(m + 1, r)
return root
return helper(0, len(nums) - 1)The recursive approach can be converted to an iterative one using an explicit stack. We store pending work items on the stack, where each item contains a node to be filled and the array bounds it should use. This simulates the recursive call stack and processes each subtree systematically without recursion.
null.(0, n-1) onto a stack.(l, r).nums[mid].l <= mid - 1), create a left child and push it with bounds (l, mid - 1).mid + 1 <= r), create a right child and push it with bounds (mid + 1, r).# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
if not nums:
return None
root = TreeNode(0)
stack = [(root, 0, len(nums) - 1)]
while stack:
node, l, r = stack.pop()
m = (l + r) // 2
node.val = nums[m]
if l <= m - 1:
node.left = TreeNode(0)
stack.append((node.left, l, m - 1))
if m + 1 <= r:
node.right = TreeNode(0)
stack.append((node.right, m + 1, r))
return rootWhen recursively building subtrees, a common mistake is including the middle element in one of the subarrays, leading to infinite recursion or duplicate nodes.
# Wrong - includes mid in left subtree
root.left = helper(l, m) # should be m - 1
# Correct
root.left = helper(l, m - 1)
root.right = helper(m + 1, r)For arrays with even length, the middle can be either (l + r) // 2 or (l + r + 1) // 2. While both produce valid height-balanced BSTs, inconsistency can cause confusion. The problem accepts either choice, but stick with one consistently.