Given an array arr[] of distinct integers. Find the number of Binary Search Trees that can be made using each element in arr[] as a root node. Examples:
Approach: Using Catalan numbers - O(n log(n)) Time and O(n) Space
If we pick node k as the root:
All nodes with values less than k must go to the left subtree.
All nodes with values greater than k must go to the right subtree.
The left and right subtrees themselves each must form valid BSTs, and their counts depend on how many nodes they contain.
Thus,
No. of BSTs rooted at k
= No. of BSTs with (k1) nodes on the left * No. of BSTs with (k2) nodes on the right
= T(k1) * T(k2)
such that T(i) denotes the number of BSTs with i distinct values.
where: k1 = number of elements less than k, k2 = number of elements greater than k, and k1+k2=n−1
For a sorted list of nodes a1,a2,…,an, each element acts as the root. Thus, the total number of BSTs is:
T(n)=∑(i=1 to n) T(i−1)×T(n−i)
This is because for element at index i( 1 ≤ i ≤ n), there are i-1 elements on left and n-i elements on right.
and T(0) = 1, T(1) = 1, as there is only one BST with either 0 or 1 element.
This recurrence is the same as that of the Catalan numbers, so the number of BSTs with n distinct nodes is Cn.
Cn=∑(i=0 to n−1) Ci×C(n−1−i)
and, C0=1, C1 = 1.
Therefore, using this we can say that the number of BSTs with element k as the root node are:
C(i) * C(n-i-1)
where i is the the number of nodes with values less than k.
C++
//Driver Code Starts#include<vector>#include<iostream>#include<algorithm>usingnamespacestd;//Driver Code Ends// Precompute factorials up to 2*nvector<int>computeFact(intnum){vector<int>fact(num+1);fact[0]=1;for(inti=1;i<=num;i++)fact[i]=fact[i-1]*i;returnfact;}// Compute nth Catalan number using precomputed factorialsintcatalan(intn,vector<int>&fact){returnfact[2*n]/(fact[n]*fact[n+1]);}// Function to count number of BSTs for each element as rootvector<int>countBSTs(vector<int>&arr){intn=arr.size();vector<vector<int>>sorted;// Pair each element with its index and sort by valuefor(inti=0;i<n;i++)sorted.push_back({arr[i],i});sort(sorted.begin(),sorted.end());// Precompute factorials up to 2*nvector<int>fact=computeFact(2*n);vector<int>numBSTs(n);// Compute BST count for each element as rootfor(inti=0;i<n;i++){intj=sorted[i][1];numBSTs[j]=catalan(i,fact)*catalan(n-i-1,fact);}returnnumBSTs;}//Driver Code Startsintmain(){vector<int>arr={2,1,3};vector<int>numBSTs=countBSTs(arr);for(intval:numBSTs)cout<<val<<" ";cout<<endl;return0;}//Driver Code Ends
Java
//Driver Code Startsimportjava.util.Arrays;importjava.util.ArrayList;importjava.util.Collections;importjava.util.Comparator;classGFG{//Driver Code Ends// Precompute factorials up to 2*nstaticArrayList<Integer>computeFact(intnum){ArrayList<Integer>fact=newArrayList<>(Collections.nCopies(num+1,1));for(inti=1;i<=num;i++)fact.set(i,fact.get(i-1)*i);returnfact;}// Compute nth Catalan number using precomputed factorialsstaticintcatalan(intn,ArrayList<Integer>fact){returnfact.get(2*n)/(fact.get(n)*fact.get(n+1));}// Function to count number of BSTs for each element as rootstaticArrayList<Integer>countBSTs(int[]arr){intn=arr.length;int[][]sorted=newint[n][2];// Pair each element with its index and sort by valuefor(inti=0;i<n;i++){sorted[i][0]=arr[i];sorted[i][1]=i;}Arrays.sort(sorted,Comparator.comparingInt(a->a[0]));ArrayList<Integer>fact=computeFact(2*n);ArrayList<Integer>numBSTs=newArrayList<>(Collections.nCopies(n,0));// Compute BST count for each element as rootfor(inti=0;i<n;i++){intj=sorted[i][1];numBSTs.set(j,catalan(i,fact)*catalan(n-i-1,fact));}returnnumBSTs;}//Driver Code Startspublicstaticvoidmain(String[]args){intarr[]={2,1,3};ArrayList<Integer>numBSTs=countBSTs(arr);for(intval:numBSTs){System.out.print(val+" ");}System.out.println();}}//Driver Code Ends
Python
#Driver Code Startsimportmath#Driver Code Ends# Precompute factorials up to 2*ndefcomputeFact(num):fact=[1]*(num+1)foriinrange(1,num+1):fact[i]=fact[i-1]*ireturnfact# Compute nth Catalan number using precomputed factorialsdefcatalan(n,fact):returnfact[2*n]//(fact[n]*fact[n+1])# Function to count number of BSTs for each element as rootdefcountBSTs(arr):n=len(arr)sortedArr=sorted([(val,idx)foridx,valinenumerate(arr)])fact=computeFact(2*n)numBsts=[0]*n# Compute BST count for each element as rootfori,(val,idx)inenumerate(sortedArr):numBsts[idx]=catalan(i,fact)*catalan(n-i-1,fact)returnnumBsts#Driver Code Startsif__name__=="__main__":arr=[2,1,3]numBSTs=countBSTs(arr)print(*numBSTs)#Driver Code Ends
C#
//Driver Code StartsusingSystem;usingSystem.Collections.Generic;usingSystem.Linq;classGFG{//Driver Code Ends// Precompute factorials up to 2*nstaticList<int>computeFact(intnum){List<int>fact=Enumerable.Repeat(1,num+1).ToList();for(inti=1;i<=num;i++)fact[i]=fact[i-1]*i;returnfact;}// Compute nth Catalan number using precomputed factorialsstaticintcatalan(intn,List<int>fact){returnfact[2*n]/(fact[n]*fact[n+1]);}// Function to count number of BSTs for each element as rootstaticList<int>countBSTs(int[]arr){intn=arr.Length;varsorted=arr.Select((val,idx)=>new{val,idx}).OrderBy(x=>x.val).ToArray();List<int>fact=computeFact(2*n);List<int>numBSTs=Enumerable.Repeat(0,n).ToList();// Compute BST count for each element as rootfor(inti=0;i<n;i++){intj=sorted[i].idx;numBSTs[j]=catalan(i,fact)*catalan(n-i-1,fact);}returnnumBSTs;}//Driver Code StartsstaticvoidMain(){int[]arr={2,1,3};List<int>numBSTs=countBSTs(arr);Console.WriteLine(string.Join(" ",numBSTs));}}//Driver Code Ends
JavaScript
// Precompute factorials up to 2*nfunctioncomputeFact(num){constfact=Array(num+1).fill(1);for(leti=1;i<=num;i++)fact[i]=fact[i-1]*i;returnfact;}// Compute nth Catalan number using precomputed factorialsfunctioncatalan(n,fact){returnfact[2*n]/(fact[n]*fact[n+1]);}// Function to count number of BSTs for each element as rootfunctioncountBSTs(arr){constn=arr.length;constsorted=arr.map((val,idx)=>({val,idx})).sort((a,b)=>a.val-b.val);// Precompute factorials up to 2*nconstfact=computeFact(2*n);constnumBSTs=Array(n).fill(0);// Compute BST count for each element as rootfor(leti=0;i<n;i++){constj=sorted[i].idx;numBSTs[j]=catalan(i,fact)*catalan(n-i-1,fact);}returnnumBSTs;}// Driver Code//Driver Code Startsconstarr=[2,1,3];constnumBSTs=countBSTs(arr)console.log(...numBSTs);//Driver Code Ends