20. Number of BST From Array
โ GFG solution to the Number of BST From Array problem: count unique BSTs possible with each element as root using Catalan numbers and dynamic programming. ๐
The problem can be found at the following link: ๐ Question Link
๐งฉ Problem Description
You are given an integer array arr[]
containing distinct elements. Your task is to return an array where the ith element denotes the number of unique BSTs formed when arr[i]
is chosen as the root.
In a Binary Search Tree (BST), all elements in the left subtree are smaller than the root, and all elements in the right subtree are greater than the root. The problem requires calculating how many structurally unique BSTs can be formed for each element when it serves as the root node.
๐ Examples
Example 1
Input: arr[] = [2, 1, 3]
Output: [1, 2, 2]
Explanation:
- When 2 is root: left subtree has 1 element (1), right subtree has 1 element (3)
Number of BSTs = C(1) * C(1) = 1 * 1 = 1
- When 1 is root: left subtree has 0 elements, right subtree has 2 elements (2, 3)
Number of BSTs = C(0) * C(2) = 1 * 2 = 2
- When 3 is root: left subtree has 2 elements (1, 2), right subtree has 0 elements
Number of BSTs = C(2) * C(0) = 2 * 1 = 2
Example 2
Input: arr[] = [2, 1]
Output: [1, 1]
Explanation:
- When 2 is root: left has 1 element (1), right has 0 elements
Number of BSTs = C(1) * C(0) = 1 * 1 = 1
- When 1 is root: left has 0 elements, right has 1 element (2)
Number of BSTs = C(0) * C(1) = 1 * 1 = 1
๐ Constraints
$1 \le \text{arr.size()} \le 6$
$1 \le \text{arr}[i] \le 15$
โ
My Approach
The optimal solution uses Catalan Numbers combined with sorting and indexing to determine BST counts efficiently:
Catalan Number with Dynamic Programming
Sort and Index Mapping:
Create pairs of (value, original_index) for each array element.
Sort these pairs by value to determine relative ordering.
After sorting, the position
i
tells us how many elements are smaller (left subtree size = i) and how many are larger (right subtree size = n - i - 1).
Precompute Catalan Numbers:
The nth Catalan number C(n) represents the number of structurally unique BSTs with n nodes.
Use dynamic programming: C(n) = ฮฃ(C(i) * C(n-i-1)) for i from 0 to n-1.
Precompute all Catalan numbers from 0 to n.
Calculate BST Count for Each Element:
For element at sorted position i:
Left subtree can have C(i) unique structures (i smaller elements)
Right subtree can have C(n-i-1) unique structures (n-i-1 larger elements)
Total BSTs with this element as root = C(i) * C(n-i-1)
Map Back to Original Indices:
Store results at original positions using the saved indices.
๐ Time and Auxiliary Space Complexity
Expected Time Complexity: O(nยฒ + n log n), as we perform O(nยฒ) operations to compute Catalan numbers using nested loops and O(n log n) for sorting the array. The overall complexity is dominated by the Catalan computation and sorting.
Expected Auxiliary Space Complexity: O(n), as we use additional space for storing pairs (value, index), Catalan numbers array, and result array, all proportional to the input size.
๐งโ๐ป Code (C++)
class Solution {
public:
vector<int> countBSTs(vector<int>& arr) {
int n = arr.size();
vector<pair<int,int>> p(n);
for (int i = 0; i < n; i++) p[i] = {arr[i], i};
sort(p.begin(), p.end());
vector<long> c(n + 1);
c[0] = c[1] = 1;
for (int i = 2; i <= n; i++) {
for (int j = 0; j < i; j++)
c[i] += c[j] * c[i - j - 1];
}
vector<int> res(n);
for (int i = 0; i < n; i++)
res[p[i].second] = c[i] * c[n - i - 1];
return res;
}
};
โ Code (Java)
class Solution {
public ArrayList<Integer> countBSTs(int[] arr) {
int n = arr.length;
int[][] p = new int[n][2];
for (int i = 0; i < n; i++) {
p[i][0] = arr[i];
p[i][1] = i;
}
Arrays.sort(p, (a, b) -> a[0] - b[0]);
long[] c = new long[n + 1];
c[0] = c[1] = 1;
for (int i = 2; i <= n; i++) {
for (int j = 0; j < i; j++)
c[i] += c[j] * c[i - j - 1];
}
ArrayList<Integer> res = new ArrayList<>();
for (int i = 0; i < n; i++) res.add(0);
for (int i = 0; i < n; i++)
res.set(p[i][1], (int)(c[i] * c[n - i - 1]));
return res;
}
}
๐ Code (Python)
class Solution:
def countBSTs(self, arr):
n = len(arr)
p = sorted((arr[i], i) for i in range(n))
c = [0] * (n + 1)
c[0] = c[1] = 1
for i in range(2, n + 1):
for j in range(i):
c[i] += c[j] * c[i - j - 1]
res = [0] * n
for i in range(n):
res[p[i][1]] = c[i] * c[n - i - 1]
return res
๐ง Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: ๐ฌ Any Questions?. Let's make this learning journey more collaborative!
โญ If you find this helpful, please give this repository a star! โญ
๐Visitor Count
Last updated