Check Unique BST's

Last Updated : 11 Jul, 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.

blobid1_1749204361


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

blobid2_1749204402
Try It Yourself
redirect icon

[Naive Approach] Generate All Unique BSTs - O(Cn × n) Time and O(Cn × n) Space

The idea is to recursively try every node as the root. For each root, recursively count the number of BSTs that can be formed by the left and right subtrees, multiply these counts, and add the results for all possible roots.

Working of Approach:

  • Recursively choose every node from 1 to n as the root of the BST.
  • For each root, recursively count the number of BSTs that can be formed by the left and right subtrees.
  • Multiply the counts of the left and right subtrees and add the result to the answer.
  • After considering all possible roots, return the total number of unique BSTs.
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] Using 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 that can be formed by the left and right subtrees, and add the result to dp[i]. Fill the dp array iteratively 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.
C++
#include <iostream>
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