Bell Numbers (Number of Ways to Partition a Set)

Last Updated : 21 Jun, 2026

Given an integer n representing a set of n distinct elements, find the number of ways to partition the set into one or more non-empty subsets.

  • The order of subsets does not matter, and every element must belong to exactly one subset.
  • Since the answer can be very large, return it modulo 10^9+7.

Examples: 

Input: n = 2
Output: 2
Explanation: Let the set be {1, 2}, the possible partitions are: {{1}, {2}} and {{1, 2}}. Hence, the answer is 2.

Input: n = 3
Output: 5
Explanation: Let the set be {1, 2, 3}, there are 5 distinct ways to partition the elements into one or more non-empty subsets. Hence, the answer is 5.

Try It Yourself
redirect icon

[Naive Approach] Using Recursion on Stirling Numbers – O(2^n) Time and O(n) Space

A Bell Number counts the total number of ways to partition a set of n elements into any number of non-empty subsets.

Let S(n, k) represents the number of ways to partition n elements into exactly k non-empty subsets. The Bell Number is simply the sum of S(n, k) over all k from 1 to n. The number S(n, k) is called Sterling Number

How do we make k subsets?

To place the nth element, we have two choices:

  • Drop it into one of the existing subsets. We recursively call for n-1 and k.
  • Start a brand new subset of its own. We recursively call for n-1 and k - 1.

Trying both choices for every element and recursing down to the base case gives us the count.

C++
#include <bits/stdc++.h>
using namespace std;

int stirling(int n, int k) {
    if (n == 0 && k == 0) return 1;
    if (n == 0 || k == 0) return 0;
    if (k > n) return 0;
    if (k == 1 || k == n) return 1;

    // Either nth element joins existing subset or forms new one
    return k * stirling(n - 1, k) + stirling(n - 1, k - 1);
}

int bellNumber(int n) {
    int res = 0;

    // Sum Stirling numbers for all possible subset counts
    for (int k = 1; k <= n; k++)
        res += stirling(n, k);

    return res;
}

int main() {
    int n = 2;
    cout << bellNumber(n) << endl;
    return 0;
}
Java
class GfG {

    static int stirling(int n, int k) {
        if (n == 0 && k == 0) return 1;
        if (n == 0 || k == 0) return 0;
        if (k > n) return 0;
        if (k == 1 || k == n) return 1;

        // Either nth element joins existing subset or forms new one
        return k * stirling(n - 1, k) + stirling(n - 1, k - 1);
    }

    static int bellNumber(int n) {
        int res = 0;

        // Sum Stirling numbers for all possible subset counts
        for (int k = 1; k <= n; k++)
            res += stirling(n, k);

        return res;
    }

    public static void main(String[] args) {
        int n = 2;
        System.out.println(bellNumber(n));
    }
}
Python
def stirling(n, k):
    if n == 0 and k == 0:
        return 1
    if n == 0 or k == 0:
        return 0
    if k > n:
        return 0
    if k == 1 or k == n:
        return 1

    # Either nth element joins existing subset or forms new one
    return k * stirling(n - 1, k) + stirling(n - 1, k - 1)

def bellNumber(n):
    res = 0

    # Sum Stirling numbers for all possible subset counts
    for k in range(1, n + 1):
        res += stirling(n, k)

    return res

if __name__ == "__main__":
    n = 2
    print(bellNumber(n))
C#
using System;

class GfG {

    static int stirling(int n, int k) {
        if (n == 0 && k == 0) return 1;
        if (n == 0 || k == 0) return 0;
        if (k > n) return 0;
        if (k == 1 || k == n) return 1;

        // Either nth element joins existing subset or forms new one
        return k * stirling(n - 1, k) + stirling(n - 1, k - 1);
    }

    static int bellNumber(int n) {
        int res = 0;

        // Sum Stirling numbers for all possible subset counts
        for (int k = 1; k <= n; k++)
            res += stirling(n, k);

        return res;
    }

    static void Main() {
        int n = 2;
        Console.WriteLine(bellNumber(n));
    }
}
JavaScript
function stirling(n, k) {
    if (n === 0 && k === 0) return 1;
    if (n === 0 || k === 0) return 0;
    if (k > n) return 0;
    if (k === 1 || k === n) return 1;

    // Either nth element joins existing subset or forms new one
    return k * stirling(n - 1, k) + stirling(n - 1, k - 1);
}

function bellNumber(n) {
    let res = 0;

    // Sum Stirling numbers for all possible subset counts
    for (let k = 1; k <= n; k++)
        res += stirling(n, k);

    return res;
}

// Driver code
const n = 2;
console.log(bellNumber(n));

Output
2

[Expected Approach] Using Bell Triangle with Space Optimization – O(n^2) Time and O(n) Space

A simple way to optimize the above approach is to use Dynamic Programming by storing solutions of subproblems. We create a 2D dp[][] array of size (n+1)*(n+1) and compute results as dp[i][j] = j * dp[i - 1][j] + dp[i - 1][j - 1]. If we observe carefully, we can notice that the current row is dependent on the previous row.

A Bell Triangle is like Pascal's Triangle - each row is built only from the row directly above it. So instead of storing the whole triangle, we just keep the previous row, build the current row from it, and discard the old one. The first number of row n is our answer.

Below is a sample Bell Triangle for first few Bell Numbers. 

1
1 2
2 3 5
5 7 10 15
15 20 27 37 52

Step By Step Implementation:

  • Start with prev = [1], representing row 0 of the Bell Triangle.
  • For row i from 1 to n, create a new row curr of size i+1.
  • Set curr[0] to the last element of prev — this carries the row over.
  • Fill the rest: curr[j] = prev[j-1] + curr[j-1], taking the diagonal-left and left neighbor.
  • After building row n, discard prev and return curr[0] (now stored back in prev) as the Bell Number.
C++
#include <bits/stdc++.h>
using namespace std;

int bellNumber(int n) {
    const int MOD = 1e9 + 7;

    // Rolling array - only store previous row instead of full triangle
    vector<long long> prev = {1};

    for (int i = 1; i <= n; i++) {
        vector<long long> curr(i + 1, 0);

        // First element of current row comes from
        // the last element of previous row.
        curr[0] = prev[prev.size() - 1];

        for (int j = 1; j <= i; j++) {

            // Build Bell Triangle using the cell
            // above-left and the previous cell.
            curr[j] = (prev[j - 1] + curr[j - 1]) % MOD;
        }
        prev = curr;
    }
    return prev[0];
}

int main() {
    int n = 2;
    cout << bellNumber(n) << endl;
    return 0;
}
Java
class GfG {

    static int bellNumber(int n) {
        int MOD = 1_000_000_007;

        // Rolling array - only store previous row instead of full triangle
        long[] prev = {1};

        for (int i = 1; i <= n; i++) {
            long[] curr = new long[i + 1];

            // First element of current row comes from
            // the last element of previous row.
            curr[0] = prev[prev.length - 1];

            for (int j = 1; j <= i; j++) {

                // Build Bell Triangle using the cell
                // above-left and the previous cell.
                curr[j] = (prev[j - 1] + curr[j - 1]) % MOD;
            }
            prev = curr;
        }
        return (int) prev[0];
    }

    public static void main(String[] args) {
        int n = 2;
        System.out.println(bellNumber(n));
    }
}
Python
def bellNumber(n):
    MOD = 1_000_000_007

    # Rolling array - only store previous row instead of full triangle
    prev = [1]

    for i in range(1, n + 1):
        curr = [0] * (i + 1)

        # First element of current row comes from
        # the last element of previous row.
        curr[0] = prev[-1]

        for j in range(1, i + 1):

            # Build Bell Triangle using the cell
            # above-left and the previous cell.
            curr[j] = (prev[j - 1] + curr[j - 1]) % MOD

        prev = curr

    return prev[0]

if __name__ == "__main__":
    n = 2
    print(bellNumber(n))
C#
using System;

class GfG {

    static int bellNumber(int n) {
        int MOD = 1_000_000_007;

        // Rolling array - only store previous row instead of full triangle
        long[] prev = {1};

        for (int i = 1; i <= n; i++) {
            long[] curr = new long[i + 1];

            // First element of current row comes from
            // the last element of previous row.
            curr[0] = prev[prev.Length - 1];

            for (int j = 1; j <= i; j++) {

                // Build Bell Triangle using the cell
                // above-left and the previous cell.
                curr[j] = (prev[j - 1] + curr[j - 1]) % MOD;
            }
            prev = curr;
        }
        return (int) prev[0];
    }

    static void Main() {
        int n = 2;
        Console.WriteLine(bellNumber(n));
    }
}
JavaScript
function bellNumber(n) {
    const MOD = 1_000_000_007;

    // Rolling array - only store previous row instead of full triangle
    let prev = [1];

    for (let i = 1; i <= n; i++) {
        const curr = new Array(i + 1).fill(0);

        // First element of current row comes from
        // the last element of previous row.
        curr[0] = prev[prev.length - 1];

        for (let j = 1; j <= i; j++) {

            // Build Bell Triangle using the cell
            // above-left and the previous cell.
            curr[j] = (prev[j - 1] + curr[j - 1]) % MOD;
        }
        prev = curr;
    }
    return prev[0];
}

// Driver code
const n = 2;
console.log(bellNumber(n));

Output
2
Comment