VOOZH about

URL: https://www.geeksforgeeks.org/dsa/count-number-of-ways-to-partition-a-set-into-k-subsets/

⇱ Count number of ways to partition a set into k subsets - GeeksforGeeks


  • Courses
  • Tutorials
  • Interview Prep

Count number of ways to partition a set into k subsets

Last Updated : 23 Jul, 2025

Given two numbers n and k where n represents a number of elements in a set, find a number of ways to partition the set into k subsets.
Example:

Input: n = 3, k = 2
Output: 3
Explanation: Let the set be [1, 2, 3], we can partition it into 3 subsets in the following ways [[1,2], [3]], [[1], [2,3]], [[1,3], [2]].

Input: n = 3, k = 1
Output: 1
Explanation: There is only one way [[1, 2, 3]].

Using Recursion - O(2^n) Time and O(n) Space

We can recursively calculate the number of ways to partition a set of n elements by considering each element and either placing it in an existing subset or creating a new subset. For each element, we calculate the number of ways to partition the remaining n-1 elements into k subsets and then sum these values for all possible k. This gives us the following recurrence relation for Stirling numbers of the second kind:

  • The previous n – 1 elements are divided into k partitions, i.e S(n-1, k) ways. Put this nth element into one of the previous k partitions. So, count = k * S(n-1, k)
  • The previous n – 1 elements are divided into k – 1 partitions, i.e S(n-1, k-1) ways. Put the nth element into a new partition ( single element partition). So, count = S(n-1, k-1)

Base case: Return 0 for invalid cases (n == 0, k == 0, or k > n) and 1 for trivial cases (k == 1 or k == n).

Total count = S(n, k) = k * S( n - 1, k) + S(n - 1, k - 1)


Output
15

Using Top-Down DP (Memoization) - O(n * k) Time and O(n * k) Space 

If we notice carefully, we can observe that the above recursive solution holds the following two properties of Dynamic Programming:

1. Optimal Substructure: The number of ways to partition a set of n elements into k subsets depends on two smaller subproblems:

  • The number of ways to partition the first n-1 elements into k subsets, and
  • The number of ways to partition the first n-1 elements into k-1 subsets and then add the new element as its own subset. By combining these optimal solutions, we can efficiently calculate the total number of ways to partition the set.

2. Overlapping Subproblems: In the recursive approach, certain subproblems are recalculated multiple times. For example, when computing S(n, k), the subproblems S(n-1, k) and S(n-1, k-1) are recomputed multiple times. This redundancy leads to overlapping subproblems, which can be avoided using memoization or tabulation. Below is recursion tree of countP(10, 7). The subproblem countP(8,6) or CP(8,6) is called multiple times.

👁 Image

  • The recursive solution involves two parameters: n (the number of elements) and k (the number of subsets).
  • We create a 2D memoization table of size (n + 1) x (k + 1) to store results for all combinations of n and k.
  • We initialize the table with -1 to indicate uncomputed subproblems, we check if the value at memo[n][k] is -1. If it is, we proceed to compute the result. otherwise, we return the stored result.

Output
15

Using Bottom-Up DP (Tabulation) - O(n * k) Time and O(n * k) Space

The approach is similar to the previous one, but instead of solving the problem recursively, we can calculate the solution using a bottom-up dynamic programming approach. We maintain a 2D table dp[][]where dp[i][j] represents the number of ways to partition a set of i elements into j subsets.

Base Case:

  • For i = 0 and 0 <= j < n, dp[0][j] = 0 (no elements to partition into subsets).
  • For j = 0 and 0 <= i < n, dp[i][0] = 0(cannot partition i elements into 0 subsets).
  • For i = j, dp[i][j] = 1(one way to partition i elements into i subsets).

Recursive Case:

  • For i > 1 and j > 1,
  • dp[i][j] = j * dp[i-1][j] + dp[i-1][j - 1]
  • This formula arises from considering two options: either placing the i-th element in one of the existing subsets (which is j * dp[i-1][j]) or placing it in a new subset (dp[i-1][j-1]).

Output
15

Using Space Optimized DP - O(n * k) Time and O(n) Space

In previous approach the current value dp[i][j] is only depend upon the current and previous row values of DP. So to optimize the space complexity we use a single 1D array to store the computations.

  • Create a 1D vector dp of size n+1.
  • Set a base case dp[0] = 1 .
  • Now iterate over subproblems by the help of nested loop and get the current value from previous computations.
  • Initialize variable prev and temp used to store the previous values from current computations.
  • After every iteration assign the value of temp to prev  for further iteration.
  • At last return and print the final answer stored in dp[n].

Output
15

Related article:

Comment