
Problem Statement
Given an integer array named nums
, where the numbers are organized in an ascending order, the task is to convert this array into a height-balanced binary search tree (BST). A height-balanced BST is one in which the depth of the two subtrees of every node never differ by more than one. This balance is crucial for ensuring that operations such as search, insert, and delete can be performed efficiently (in logarithmic time complexity) relative to the height of the tree.
Examples
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] <= 104
nums
is sorted in a strictly increasing order.
Approach and Intuition
The approach for converting a sorted array into a height-balanced BST leverages the properties of binary search due to the sorted nature of the array. Here is the step-by-step process:
Identify the middle element of the array to be the root of the BST:
- This helps in maintaining the balance as it ensures that the number of nodes on the left and right subtrees are as equal as possible.
Recursively apply the same process to the left half of the array to construct the left subtree.
- The middle element of this left subsection becomes the left child of the root.
Recursively apply the same process to the right half of the array to construct the right subtree.
- The middle element of this right subsection becomes the right child of the root.
Continue this division until each subsection cannot be divided further (i.e., it becomes a single element or empty), at which point the recursion ends.
Through this recursive divide-and-conquer strategy, the constructed BST naturally remains height-balanced. Each recursive step selects a new root that balances the number of nodes in the left and right subtrees of that particular subtree, contributing to the overall balance of the tree.
Example 1 from the problem statement illustrates this:
- The array
[-10, -3, 0, 5, 9]
has0
as its middle element. The subtrees rooted at-3
(left) and9
(right) are recursively constructed using the same strategy. - Although the exact left-right arrangement might differ (as the explanation allows two structures), both are valid height-balanced BSTs.
- The array
Example 2 shows that smaller trees (like those with 2 elements) can also follow the rule by taking the last element as the root (to ensure at most one level of depth difference), demonstrating the flexibility and correctness of the approach across varied input sizes.
This methodical conversion guarantees the height-balancing of the resultant BST, promoting operations within optimal time complexities tied to the tree's height. The constraints ensure the handling of reasonably large inputs, validating this efficient approach for substantial datasets.
Solutions
- C++
- Java
- C
- JavaScript
- Python
class Solution {
public:
TreeNode* transformSortedArrayToBST(vector<int>& arr) {
return buildBST(arr, 0, arr.size() - 1);
}
private:
TreeNode* buildBST(vector<int>& arr, int start, int end) {
if (start > end) return nullptr;
int middle = (start + end) / 2;
if ((start + end) % 2 == 1) middle += rand() % 2;
TreeNode* node = new TreeNode(arr[middle]);
node->left = buildBST(arr, start, middle - 1);
node->right = buildBST(arr, middle + 1, end);
return node;
}
};
To convert a sorted array into a balanced binary search tree (BST), create a function in C++ that employs recursion to find the middle element of the array, inserting it as a node and recursively building the left subtree from the elements before the middle and the right subtree from the elements after the middle. Implement this by defining a class Solution
with two functions:
transformSortedArrayToBST
which acts as the main function and initiates the BST transformation process with boundary indices.buildBST
, a private recursive helper function that divides the array and creates aTreeNode
at each division:- Determine the base condition where the start index exceeds the end index, returning
nullptr
. - Calculate the mid-point. If the index sum is odd, apply a random adjustment to ensure balance.
- Recursively allocate nodes to the left child and right child of the current
TreeNode
.
- Determine the base condition where the start index exceeds the end index, returning
The program effectively uses the properties of the sorted array to ensure each subtree node is inserted at its correct position, thus maintaining the characteristic of the binary search tree. The randomness in selecting the middle index aids in maintaining balance, especially useful in scenarios where distinct set-ups might cause imbalances in tree structure. This solution provides an efficient and straightforward approach to construct a balanced BST, leveraging the binary search principle.
class Solution {
int[] elements;
Random randomGenerator = new Random();
public TreeNode constructBST(int start, int end) {
if (start > end) return null;
// Pick a random index for the root
int midpoint = (start + end) / 2;
if ((start + end) % 2 == 1) midpoint += randomGenerator.nextInt(2);
// Build the tree node by node
TreeNode rootNode = new TreeNode(elements[midpoint]);
rootNode.left = constructBST(start, midpoint - 1);
rootNode.right = constructBST(midpoint + 1, end);
return rootNode;
}
public TreeNode sortedArrayToBST(int[] elements) {
this.elements = elements;
return constructBST(0, elements.length - 1);
}
}
The provided Java solution efficiently demonstrates how to convert a sorted array into a balanced Binary Search Tree (BST). The process implemented in the code ensures that the tree remains balanced, thus maintaining optimal search operations.
- The
Solution
class stores the array elements in a privateelements
array and includes arandomGenerator
to help vary the choice of the root node slightly by randomness when the array length is odd. - The
constructBST
function recursively creates the BST:- Base case: if the
start
index is greater than theend
index, the recursion halts, returningnull
– indicative of no subtree. - A root node is chosen using a combination of midpoint calculation and an optional random adjustment to balance the tree and to avoid skewed tree structures, especially useful in scenarios involving sorted data.
- Recursion continues to construct the left subtree using the sub-array to the left of the midpoint and the right subtree using the sub-array on the right.
- Base case: if the
- The
sortedArrayToBST
function sets up the initial state by storing the reference to the input array and calling theconstructBST
function with indices covering the entire range of the array.
Thanks to the smart midpoint selection randomized slightly, this algorithm focuses not only on the BST property but also emphasizes maintaining a balance, resulting in a logarithmic height in expectation, conducive to efficient operations like lookups, insertions, and deletions.
struct TreeNode* buildBST(int* elements, int start, int end) {
if (start > end) return NULL;
int mid = (start + end) / 2;
if ((start + end) % 2) mid += rand() % 2;
struct TreeNode* node = (struct TreeNode*)malloc(sizeof(struct TreeNode));
node->val = elements[mid];
node->left = buildBST(elements, start, mid - 1);
node->right = buildBST(elements, mid + 1, end);
return node;
}
struct TreeNode* convertSortedArrayToBST(int* elements, int size) {
return buildBST(elements, 0, size - 1);
}
To convert a sorted array into a binary search tree (BST) using C programming, follow the efficient approach implemented in the provided code. The process delves into two primary functions: buildBST
and convertSortedArrayToBST
.
buildBST
takes an array of integers (elements
), the start index (start
), and the end index (end
):- Check for the base condition where
start
exceedsend
. If true, returnNULL
indicating there's no subtree to process in this segment. - Calculate the middle index (
mid
) to use as a root for the BST node. Adjustments include adding a random offset to promote balance in the tree when there's a choice of two middle values. - Dynamically allocate a new tree node (
node
) and set its value to the element at themid
index. - Recursively build the left subtree using elements from the
start
tomid - 1
. - Similarly, build the right subtree using elements from
mid + 1
toend
. - Return the constructed
node
, now representing the root of the BST for the given segment.
- Check for the base condition where
convertSortedArrayToBST
initiates the tree construction:- It simply calls the
buildBST
function passing the entire array and its size to cover all elements.
- It simply calls the
Ensure the development environment supports C standard library for dynamic memory management (malloc
) and random number generation (rand()
). The approach taken in the script ensures the constructed BST adheres to properties of a balanced binary search tree, where heights of two child subtrees of any node differ at most by one.
var sortedArrayToBST = function (arr) {
let constructTree = function (start, end) {
if (start > end) return null;
let mid = Math.floor((start + end) / 2);
if ((start + end) % 2 === 1) mid += Math.floor(Math.random() * 2);
let node = new TreeNode(arr[mid]);
node.left = constructTree(start, mid - 1);
node.right = constructTree(mid + 1, end);
return node;
};
return constructTree(0, arr.length - 1);
};
This JavaScript code defines a function sortedArrayToBST
that constructs a balanced binary search tree (BST) from a sorted array. The process involves recursively picking the middle element of the array to ensure the resulting tree remains balanced. Here's a summary of the function execution:
- Define the function
sortedArrayToBST
which takes the sorted arrayarr
as input. - Inside, define a helper function
constructTree
that takes two parameters,start
andend
, representing the current segment of the array being processed. - Check if
start
is greater thanend
. If true, returnnull
, as this indicates that there are no elements to process in this segment. - Calculate the
mid
index of the segment. If the subsection length is odd, the middle index is adjusted randomly by 0 or 1 to enhance balance. - Create a new tree node
TreeNode
with the element at themid
index. - Recursively set the
left
child of the node by processing the subarray beforemid
. - Recursively set the
right
child by processing the subarray aftermid
. - The
constructTree
function returns the node. - The
sortedArrayToBST
function initializes the recursive construction by callingconstructTree
with the indices 0 andarr.length - 1
. - Finally, it returns the root of the constructed BST.
The approach cleverly manipulates the middle index under certain conditions to potentially improve the balance of the tree resulting from uneven array lengths. The recursion ensures each segment of the array correctly contributes to the corresponding subtree of the BST.
from random import choice
class Solution:
def convertSortedArrayToBST(self, values: List[int]) -> TreeNode:
def construct_bst(start, end):
if start > end:
return None
# Selecting a central node randomly if possible
mid = (start + end) // 2
if (start + end) % 2 == 1:
mid += choice([0, 1])
# Recursive tree creation: node -> left -> right
node = TreeNode(values[mid])
node.left = construct_bst(start, mid - 1)
node.right = construct_bst(mid + 1, end)
return node
return construct_bst(0, len(values) - 1)
The provided Python code defines a method for converting a sorted array into a binary search tree. This transformation is crucial for operations requiring binary search properties to optimize search queries, such as lookups, insertions, and deletions in logarithmic time.
The convertSortedArrayToBST
function employs a recursive helper function construct_bst
to perform this conversion:
- Checking Base Conditions: If the
start
index exceeds theend
, the recursion stops and returnsNone
, indicating no subtree is possible with the given indices. - Selecting the Root Node: Calculate the middle index
mid
betweenstart
andend
. If the sum ofstart
andend
is odd, adjustmid
randomly by either 0 or 1 to maintain balance in the tree. - Creating the Tree Node: Instantiate a
TreeNode
with the element at the indexmid
of the array. This node acts as the root for the current subtree. - Recursive Tree Construction: Set the left child of the node by recursively calling
construct_bst
fromstart
tomid - 1
and the right child frommid + 1
toend
.
The approach ensures each node of the final tree adheres to the properties of a binary search tree by using the middle of each sub-array slice, optionally adjusted for randomness. This division ensures both the left and right subtrees contain approximately the same number of nodes, supporting tree balance.
No comments yet.