Check Unique BST's

Last Updated : 19 Sep, 2026

Given an integer n, find the number of structurally unique Binary Search Trees (BSTs) that can be formed using the values from 1 to n (inclusive).

Examples: 

Input: n = 2
Output: 2
Explanation: for n = 2, there are 2 unique BSTs.

find_the_dominator_for_every_vertex_in_a_given_dag

Input: n = 3
Output: 5
Explanation: for n = 3, there are 5 possible BSTs.

blobid2_1749204402
Try It Yourself
redirect icon

[Naive Approach] Recursion - O(3 ^ n) Time and O(n) Space

The idea is to use Recursion, where we try every node as the root and recursively count the possible BSTs for its left and right subtrees.

  • For each root, multiply the number of BSTs possible in the left and right subtrees.
  • Add these products for all possible roots to get the total number of unique BSTs.

Why Does this Approach Work?

To understand the approach, let us write n numbers as an array [1, 2, .... n]. Let the count of all possible BSTs with n nodes be count(n). For each value i in the above array, we put [1, 2, ... i-1] into left subtree, make i as root and put [i+1, i+2, ... n] in right subtree. Hence count(n) can be written as summation of (count(i-1)*count(n-i)) where i lies in the range [1, n].

C++
#include <iostream>
using namespace std;

// Function to return the total number of possible unique BSTs.
int numTrees(int n)
{

    // Base case
    if (n <= 1)
        return 1;

    int ans = 0;

    // Try every node as the root.
    for (int root = 1; root <= n; root++)
    {

        // Count BSTs formed by the left and right subtrees.
        ans += numTrees(root - 1) * numTrees(n - root);
    }

    // Return the total number of unique BSTs.
    return ans;
}

int main()
{
    int n = 3;

    cout << numTrees(n);

    return 0;
}
Java
public class GFG {

    // Function to return the total number of possible
    // unique BSTs.
    static int numTrees(int n)
    {

        // Base case
        if (n <= 1)
            return 1;

        int ans = 0;

        // Try every node as the root.
        for (int root = 1; root <= n; root++) {

            // Count BSTs formed by the left and right
            // subtrees.
            ans += numTrees(root - 1) * numTrees(n - root);
        }

        // Return the total number of unique BSTs.
        return ans;
    }

    public static void main(String[] args)
    {
        int n = 3;

        System.out.print(numTrees(n));
    }
}
Python
# Function to return the total number of possible unique BSTs.
def numTrees(n):

    # Base case
    if n <= 1:
        return 1

    ans = 0

    # Try every node as the root.
    for root in range(1, n + 1):

        # Count BSTs formed by the left and right subtrees.
        ans += numTrees(root - 1) * numTrees(n - root)

    # Return the total number of unique BSTs.
    return ans


if __name__ == '__main__':
    n = 3

    print(numTrees(n))
C#
using System;

class GFG {
    // Function to return the total number of possible
    // unique BSTs.
    static int numTrees(int n)
    {
        // Base case
        if (n <= 1)
            return 1;

        int ans = 0;

        // Try every node as the root.
        for (int root = 1; root <= n; root++) {
            // Count BSTs formed by the left and right
            // subtrees.
            ans += numTrees(root - 1) * numTrees(n - root);
        }

        // Return the total number of unique BSTs.
        return ans;
    }

    static void Main()
    {
        int n = 3;

        Console.Write(numTrees(n));
    }
}
JavaScript
// Function to return the total number of possible unique
// BSTs.
function numTrees(n)
{

    // Base case
    if (n <= 1)
        return 1;

    let ans = 0;

    // Try every node as the root.
    for (let root = 1; root <= n; root++) {

        // Count BSTs formed by the left and right subtrees.
        ans += numTrees(root - 1) * numTrees(n - root);
    }

    // Return the total number of unique BSTs.
    return ans;
}

// Driver Code
let n = 3;

console.log(numTrees(n));

Output
5

[Expected Approach] Dynamic Programming (Tabulation) - O(n ^ 2) Time and O(n) Space

The idea is to use Dynamic Programming (Tabulation), where dp[i] stores the number of unique BSTs that can be formed using i nodes.

  • For each possible root, multiply the number of BSTs possible in the left and right subtrees and add it to dp[i].
  • Fill the dp array from 0 to n and return dp[n].

Working of Approach:

  • Create a dp array where dp[i] stores the number of unique BSTs that can be formed using i nodes.
  • Initialize the base cases: dp[0] = 1 and dp[1] = 1, as there is exactly one BST with 0 or 1 node.
  • For each number of nodes from 2 to n, try every node as the root, multiply the number of possible left and right subtrees, and add the result to dp[i].
  • After filling the dp array, return dp[n], which represents the total number of structurally unique BSTs that can be formed using n nodes.

Let us understand with an example:
Input: n = 3

  • Initialize dp[0] = 1 and dp[1] = 1, representing the number of unique BSTs with 0 and 1 node.
  • For i = 2, choose each node as the root: dp[2] = dp[0] × dp[1] + dp[1] × dp[0] = 1 + 1 = 2.
  • For i = 3, compute dp[3] = dp[0] × dp[2] + dp[1] × dp[1] + dp[2] × dp[0] = 2 + 1 + 2 = 5.
  • Store each computed value in the dp array and use it for subsequent calculations.
  • Finally, return dp[3] = 5, which is the total number of structurally unique BSTs that can be formed using 3 nodes.
blobid2_1749204402
C++
#include <iostream>
#include <vector>
using namespace std;

// Function to return the total number of possible unique BSTs.
int numTrees(int n)
{
    // dp[i] stores the number of unique BSTs
    // that can be formed using i nodes.
    int dp[n + 1];

    // Base cases.
    dp[0] = 1;
    dp[1] = 1;

    // Fill the dp[] array in a bottom-up manner.
    for (int i = 2; i <= n; i++)
    {
        dp[i] = 0;

        // Try every node as the root.
        for (int j = 1; j <= i; j++)
        {
            // If j is chosen as the root, then
            // nodes [1...j-1] form the left subtree and
            // nodes [j+1...i] form the right subtree.
            // Multiply the number of possible left and
            // right subtrees and add it to dp[i].
            dp[i] += dp[j - 1] * dp[i - j];
        }
    }

    // Return the total number of unique BSTs.
    return dp[n];
}

int main()
{
    int n = 3;

    cout << numTrees(n);

    return 0;
}
Java
public class GFG {

    // Function to return the total number of possible
    // unique BSTs.
    static int numTrees(int n)
    {
        // dp[i] stores the number of unique BSTs
        // that can be formed using i nodes.
        int[] dp = new int[n + 1];

        // Base cases.
        dp[0] = 1;
        dp[1] = 1;

        // Fill the dp[] array in a bottom-up manner.
        for (int i = 2; i <= n; i++) {
            dp[i] = 0;

            // Try every node as the root.
            for (int j = 1; j <= i; j++) {
                
                // If j is chosen as the root, then
                // nodes [1...j-1] form the left subtree and
                // nodes [j+1...i] form the right subtree.
                // Multiply the number of possible left and
                // right subtrees and add it to dp[i].
                dp[i] += dp[j - 1] * dp[i - j];
            }
        }

        // Return the total number of unique BSTs.
        return dp[n];
    }

    public static void main(String[] args)
    {
        int n = 3;

        System.out.print(numTrees(n));
    }
}
Python
# Function to return the total number of possible unique BSTs.
def numTrees(n):
    # dp[i] stores the number of unique BSTs
    # that can be formed using i nodes.
    dp = [0] * (n + 1)

    # Base cases.
    dp[0] = 1
    dp[1] = 1

    # Fill the dp[] array in a bottom-up manner.
    for i in range(2, n + 1):
        dp[i] = 0

        # Try every node as the root.
        for j in range(1, i + 1):
            
            # If j is chosen as the root, then
            # nodes [1...j-1] form the left subtree and
            # nodes [j+1...i] form the right subtree.
            # Multiply the number of possible left and
            # right subtrees and add it to dp[i].
            dp[i] += dp[j - 1] * dp[i - j]

    # Return the total number of unique BSTs.
    return dp[n]


if __name__ == '__main__':
    n = 3

    print(numTrees(n))
C#
using System;

class GFG {
    // Function to return the total number of possible
    // unique BSTs.
    static int numTrees(int n)
    {
        // dp[i] stores the number of unique BSTs
        // that can be formed using i nodes.
        int[] dp = new int[n + 1];

        // Base cases.
        dp[0] = 1;
        dp[1] = 1;

        // Fill the dp[] array in a bottom-up manner.
        for (int i = 2; i <= n; i++) {
            dp[i] = 0;

            // Try every node as the root.
            for (int j = 1; j <= i; j++) {
                
                // If j is chosen as the root, then
                // nodes [1...j-1] form the left subtree and
                // nodes [j+1...i] form the right subtree.
                // Multiply the number of possible left and
                // right subtrees and add it to dp[i].
                dp[i] += dp[j - 1] * dp[i - j];
            }
        }

        // Return the total number of unique BSTs.
        return dp[n];
    }

    static void Main()
    {
        int n = 3;

        Console.Write(numTrees(n));
    }
}
JavaScript
// Function to return the total number of possible unique
// BSTs.
function numTrees(n)
{
    // dp[i] stores the number of unique BSTs
    // that can be formed using i nodes.
    let dp = new Array(n + 1).fill(0);

    // Base cases.
    dp[0] = 1;
    dp[1] = 1;

    // Fill the dp[] array in a bottom-up manner.
    for (let i = 2; i <= n; i++) {
        dp[i] = 0;

        // Try every node as the root.
        for (let j = 1; j <= i; j++) {
            
            // If j is chosen as the root, then
            // nodes [1...j-1] form the left subtree and
            // nodes [j+1...i] form the right subtree.
            // Multiply the number of possible left and
            // right subtrees and add it to dp[i].
            dp[i] += dp[j - 1] * dp[i - j];
        }
    }

    // Return the total number of unique BSTs.
    return dp[n];
}

let n = 3;

console.log(numTrees(n));

Output
5
Comment