Recursive Algorithm to Convert a List to Binary Search Tree


Given a sorted list nums of size n, construct a binary search tree by

  1. Taking nums[k] as the root where k = floor(n / 2).
  2. Recursively constructing the left subtree using the list nums[:k]
  3. Recursively constructing the right subtree using the list nums[k + 1:]

Constraints
0 ≤ n ≤ 100,000
Example 1
Input
nums = [0, 1, 2, 3, 4]

Output:

    2
   / \
  1   4
 /   /
0   3

Recursive Algorithm to Construct Binary Search Tree

The problem itself is recursive and we can build a recursive algorithm. First, find the middle point, build a node, and recursively build its left and right tree. Since the entire list is sorted, the binary tree we build is a Binary Search Tree.

Python algorithm to Build a Binary Search Tree:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# class Tree:
#     def __init__(self, val, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def buildBST(self, nums):
        if not nums:
            return None
        k = len(nums) // 2
        root = Tree(nums[k])
        root.left = self.buildBST(nums[:k])
        root.right = self.buildBST(nums[k+1:])
        return root
# class Tree:
#     def __init__(self, val, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def buildBST(self, nums):
        if not nums:
            return None
        k = len(nums) // 2
        root = Tree(nums[k])
        root.left = self.buildBST(nums[:k])
        root.right = self.buildBST(nums[k+1:])
        return root

C++ algorithm to Build a Binary Search Tree:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
 * class Tree {
 *     public:
 *         int val;
 *         Tree *left;
 *         Tree *right;
 * };
 */
Tree* buildBST(vector<int>& nums) {
    if (nums.empty()) return nullptr;
    int k = nums.size() / 2;
    Tree* root = new Tree(nums[k]);
    auto left = vector<int>(begin(nums), begin(nums) + k);
    auto right = vector<int>(begin(nums) + k + 1, end(nums));
    root->left = buildBST(left);
    root->right = buildBST(right);
    return root;
}
/**
 * class Tree {
 *     public:
 *         int val;
 *         Tree *left;
 *         Tree *right;
 * };
 */
Tree* buildBST(vector<int>& nums) {
    if (nums.empty()) return nullptr;
    int k = nums.size() / 2;
    Tree* root = new Tree(nums[k]);
    auto left = vector<int>(begin(nums), begin(nums) + k);
    auto right = vector<int>(begin(nums) + k + 1, end(nums));
    root->left = buildBST(left);
    root->right = buildBST(right);
    return root;
}

Both implementations are O(N^2) time where N is the number of the values in the list because at each partition, we are allocating spaces and copying over the sublists. There is O(N) space where we are implicitly requiring a stack because of using stack.

If we are using the left, right pointer to avoid the sublist copying, the time complexity will be O(N):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
 * class Tree {
 *     public:
 *         int val;
 *         Tree *left;
 *         Tree *right;
 * };
 */
Tree* buildBST(vector<int>& nums) {
    if (nums.empty()) return nullptr;
    function<Tree*(vector<int>&, int, int)> build = [&](vector<int>& nums, int left, int right) {
        if (left > right) return (Tree*)NULL;
        int k = (left + right + 1) >> 1;
        Tree* root = new Tree(nums[k]);
        root->left = build(nums, left, k - 1);
        root->right = build(nums, k + 1, right);
        return root;
    };
    return build(nums, 0, nums.size() - 1);
}
/**
 * class Tree {
 *     public:
 *         int val;
 *         Tree *left;
 *         Tree *right;
 * };
 */
Tree* buildBST(vector<int>& nums) {
    if (nums.empty()) return nullptr;
    function<Tree*(vector<int>&, int, int)> build = [&](vector<int>& nums, int left, int right) {
        if (left > right) return (Tree*)NULL;
        int k = (left + right + 1) >> 1;
        Tree* root = new Tree(nums[k]);
        root->left = build(nums, left, k - 1);
        root->right = build(nums, k + 1, right);
        return root;
    };
    return build(nums, 0, nums.size() - 1);
}

–EOF (The Ultimate Computing & Technology Blog)

GD Star Rating
loading...
543 words
Last Post: Compute the Z Sum of a Matrix
Next Post: Teaching Kids Programming - Hexadecimal Numbers Conversion

The Permanent URL is: Recursive Algorithm to Convert a List to Binary Search Tree

Leave a Reply