Given an integer array nums where the elements are sorted in ascending order, convert it to a height-balanced binary search tree.
Example 1:
Input: nums = [-10,-3,0,5,9] Output: [0,-3,9,-10,null,5] Explanation: [0,-10,5,null,-3,null,9] is also accepted:![]()
Example 2:
Input: nums = [1,3] Output: [3,1] Explanation: [1,null,3] and [3,1] are both height-balanced BSTs.
Constraints:
1 <= nums.length <= 104-104 <= nums[i] <= 104nums is sorted in a strictly increasing order.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force strategy involves trying every single number from the sorted list as the starting point, or the top, of our tree. For each choice, we then explore all the possible ways to arrange the remaining numbers to see if we can build a valid and balanced family tree of numbers.
Here's how the algorithm would work step-by-step:
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def sortedArrayToBST(nums):
import itertools
def get_height(node):
if not node:
return 0
return 1 + max(get_height(node.left), get_height(node.right))
def is_balanced(root):
if not root:
return True
left_height = get_height(root.left)
right_height = get_height(root.right)
if abs(left_height - right_height) > 1:
return False
return is_balanced(root.left) and is_balanced(root.right)
def build_all_trees(available_numbers):
if not available_numbers:
yield None
return
# This loop tries every number in the current list as the root for this subtree.
for index, potential_root_value in enumerate(available_numbers):
left_side_numbers = available_numbers[:index]
right_side_numbers = available_numbers[index+1:]
# Recursively generate all possible left and right subtrees from the remaining numbers.
for left_subtree in build_all_trees(left_side_numbers):
for right_subtree in build_all_trees(right_side_numbers):
current_root = TreeNode(potential_root_value)
current_root.left = left_subtree
current_root.right = right_subtree
yield current_root
# Iterate through all permutations of the input numbers, as the root can be any element.
for number_permutation in itertools.permutations(nums):
generated_trees = list(build_all_trees(list(number_permutation)))
for potential_tree_root in generated_trees:
# After building a tree, we must check its height balance property for validity.
if is_balanced(potential_tree_root):
return potential_tree_root
return NoneTo build a balanced tree from a sorted list of numbers, we should pick the middle number as the top of the tree. This single choice naturally splits the remaining numbers into two equal-sized groups, which we can then use to build the left and right sides of the tree in the same way.
Here's how the algorithm would work step-by-step:
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def sortedArrayToBST(nums):
def build_tree_from_range(left_index, right_index):
# The base case: if the range is empty, there are no more numbers to place.
if left_index > right_index:
return None
# Picking the middle element ensures the tree remains height-balanced.
middle_index = (left_index + right_index) // 2
root_node = TreeNode(nums[middle_index])
# Recursively build the left subtree from the left half of the current range.
root_node.left = build_tree_from_range(left_index, middle_index - 1)
# Recursively build the right subtree from the right half of the current range.
root_node.right = build_tree_from_range(middle_index + 1, right_index)
return root_node
return build_tree_from_range(0, len(nums) - 1)| Case | How to Handle |
|---|---|
| Input array is empty | The recursive base case should handle this by returning null, representing an empty tree. |
| Input array has only one element | A single node is created and returned, which is by definition a valid height-balanced BST. |
| Input array has an even number of elements | Choosing either of the two middle elements as the root will produce a valid, though different, height-balanced BST. |
| Input array contains duplicate values | The standard recursive algorithm handles duplicates correctly, placing them in the tree according to BST rules. |
| Input array contains negative numbers and zero | The algorithm is agnostic to the sign of the numbers and will correctly construct the BST as long as the array is sorted. |
| Input array is very large, potentially causing a stack overflow | A deeply recursive approach might fail; an iterative solution using a stack can be used to avoid this. |
| Multiple valid height-balanced BSTs are possible | The problem allows for any valid height-balanced BST, so a consistent choice for the root (e.g., always the middle-left element) is sufficient. |
| Input array contains integer boundary values (e.g., INT_MIN, INT_MAX) | The values themselves do not affect the tree construction logic, so the standard algorithm works without modification. |