Given an integer n, the task is to generate all possible Binary Search Trees (BSTs) that can be constructed using keys from 1 to n and print their preorder traversal.
Examples:
Input: n = 2 Output: 1 2 2 1
Input: n= 3 Output: 1 2 3 1 3 2 2 1 3 3 1 2 3 2 1
How many structurally unique BSTs can be formed with keys from 1 to n?
The key observation is that for any i-th number chosen as the root, all numbers from 1 to i-1 must be in the left subtree (since they are smaller than the root), and all numbers from i+1 to n must be in the right subtree (since they are larger than the root).
If the numbers from 1 to i-1 can form x different trees and the numbers from i+1 to n can form y different trees, then for the i-th number as root, we can have x * y total unique BSTs.
Since we can choose any number from 1 to n as the root, we iterate over each possible root (from 1 to n) and calculate the total number of unique BSTs by summing up the product of the number of left and right subtrees for each root.
Upon observation, the number of structurally unique BSTs for n keys is equivalent to the n-th Catalan number, which can be computed using known formulas or dynamic programming.
Approach:
The idea is to construct all possible BSTs by considering each number from 1 to n as the root and recursively constructing the left and right subtrees. For each root i, all numbers from 1 to i-1 will form the left subtree, and numbers from i+1 to n will form the right subtree. We recursively generate all possible BSTs for the left and right subtrees and then combine each left subtree with each right subtree for the current root.
Follow the steps below to solve the problem:
Initialize a array of BSTs as empty.
For every number i from 1 to n, do the following:
Create a new node with key i, let this node be 'node'.
Recursively construct a list of all possible left subtrees from numbers 1 to i-1.
Recursively construct a list of all possible right subtrees from numbers i+1 to n.
Iterate over all possible left subtrees:
For each current left subtree, iterate over all possible right subtrees.
Attach the current left and right subtrees to 'node'.
Add the node (with attached subtrees) to the list of BSTs.
Below is the implementation of the above approach:
C++
// C++ program to find all binary trees// from 1 to n#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=right=nullptr;}};// Function to construct all possible binary trees vector<Node*>getTrees(intstart,intend){vector<Node*>trees;// Base case: If start index is greater than end, // return empty tree (nullptr)if(start>end){trees.push_back(nullptr);returntrees;}// Iterate through all values in the array // and construct left and right subtreesfor(inti=start;i<=end;++i){// Generate all left subtreesvector<Node*>leftTrees=getTrees(start,i-1);// Generate all right subtreesvector<Node*>rightTrees=getTrees(i+1,end);// Combine each left and right subtree with // the current rootfor(Node*left:leftTrees){for(Node*right:rightTrees){// Make i as rootNode*root=newNode(i);root->left=left;root->right=right;// Add the constructed tree to the list of treestrees.push_back(root);}}}returntrees;}voidpreorder(Node*root){if(root!=nullptr){cout<<root->data<<" ";preorder(root->left);preorder(root->right);}}intmain(){vector<Node*>trees=getTrees(1,3);for(inti=0;i<trees.size();++i){preorder(trees[i]);cout<<"\n";}return0;}
Java
// Java program to find all binary// trees from 1 to nimportjava.util.ArrayList;importjava.util.List;classNode{intdata;Nodeleft,right;Node(intdata){this.data=data;left=right=null;}}classGfG{// Function to construct all possible binary treesstaticList<Node>getTrees(intstart,intend){List<Node>trees=newArrayList<>();// Base case: If start index is greater than end, // return empty tree (null)if(start>end){trees.add(null);returntrees;}// Iterate through all values in the array and // construct left and right subtreesfor(inti=start;i<=end;i++){// Generate all left subtreesList<Node>leftTrees=getTrees(start,i-1);// Generate all right subtreesList<Node>rightTrees=getTrees(i+1,end);// Combine each left and right// subtree with the current rootfor(Nodeleft:leftTrees){for(Noderight:rightTrees){// Make i as rootNoderoot=newNode(i);root.left=left;root.right=right;// Add the constructed tree to the// list of treestrees.add(root);}}}returntrees;}staticvoidpreorder(Noderoot){if(root!=null){System.out.print(root.data+" ");preorder(root.left);preorder(root.right);}}publicstaticvoidmain(String[]args){List<Node>trees=getTrees(1,3);for(Nodetree:trees){preorder(tree);System.out.println();}}}
Python
# Python program to find all binary# trees from 1 to nclassNode:def__init__(self,data):self.data=dataself.left=Noneself.right=None# Function to construct all possible# binary trees defget_trees(start,end):trees=[]# Base case: If start index is greater than end, # return empty tree (None)ifstart>end:trees.append(None)returntrees# Iterate through all values in the array and # construct left and right subtreesforiinrange(start,end+1):# Generate all left subtreesleft_trees=get_trees(start,i-1)# Generate all right subtreesright_trees=get_trees(i+1,end)# Combine each left and right subtree # with the current rootforleftinleft_trees:forrightinright_trees:# Make i as rootroot=Node(i)root.left=leftroot.right=right# Add the constructed tree to # the list of treestrees.append(root)returntreesdefpreorder(root):ifrootisnotNone:print(root.data,end=" ")preorder(root.left)preorder(root.right)if__name__=="__main__":trees=get_trees(1,3)fortreeintrees:preorder(tree)print()
C#
// C# program to find all binary trees // from 1 to nusingSystem;usingSystem.Collections.Generic;classNode{publicintdata;publicNodeleft,right;publicNode(intdata){this.data=data;this.left=this.right=null;}}classGfG{// Function to construct all possible binary trees staticList<Node>GetTrees(intstart,intend){List<Node>trees=newList<Node>();// Base case: If start index is greater than end, // return empty tree (null)if(start>end){trees.Add(null);returntrees;}// Iterate through all values in the array and // construct left and right subtreesfor(inti=start;i<=end;i++){// Generate all left subtreesList<Node>leftTrees=GetTrees(start,i-1);// Generate all right subtreesList<Node>rightTrees=GetTrees(i+1,end);// Combine each left and right subtree // with the current rootforeach(NodeleftinleftTrees){foreach(NoderightinrightTrees){// Make i as rootNoderoot=newNode(i);root.left=left;root.right=right;// Add the constructed tree to// the list of treestrees.Add(root);}}}returntrees;}staticvoidPreorder(Noderoot){if(root!=null){Console.Write(root.data+" ");Preorder(root.left);Preorder(root.right);}}staticvoidMain(string[]args){List<Node>trees=GetTrees(1,3);foreach(Nodetreeintrees){Preorder(tree);Console.WriteLine();}}}
JavaScript
// JavaScript program to find all binary// trees from 1 to nclassNode{constructor(data){this.data=data;this.left=null;this.right=null;}}// Function to construct all possible binary treesfunctiongetTrees(start,end){consttrees=[];// Base case: If start index is greater than end, // return empty tree (null)if(start>end){trees.push(null);returntrees;}// Iterate through all values in the array // and construct left and right subtreesfor(leti=start;i<=end;i++){// Generate all left subtreesconstleftTrees=getTrees(start,i-1);// Generate all right subtreesconstrightTrees=getTrees(i+1,end);// Combine each left and right subtree// with the current rootleftTrees.forEach(left=>{rightTrees.forEach(right=>{// Make i as rootconstroot=newNode(i);root.left=left;root.right=right;// Add the constructed tree to // the list of treestrees.push(root);});});}returntrees;}functionpreorder(root){if(root!==null){process.stdout.write(root.data+" ");preorder(root.left);preorder(root.right);}}consttrees=getTrees(1,3);trees.forEach(tree=>{preorder(tree);console.log();});
Output
1 2 3
1 3 2
2 1 3
3 1 2
3 2 1
Time Complexity: O(Cn * n), where Cn is the Catalan number Auxiliary Space: O(Cn * n), for storing all possible trees and the space used by the recursion stack.