Given an array arr[] of size N and an integer K, the task is to print all possible ways to split the given array into K subsets.
Examples:
Input: arr[] = { 1, 2, 3 }, K = 2
Output: { {{ 1, 2 }, { 3 }}, {{ 1, 3 }, { 2 }}, {{ 1 }, { 2, 3 }}}.Input: arr[] = { 1, 2, 3, 4 }, K = 2
Output: { {{ 1, 2, 3 }, { 4 }}, {{ 1, 2, 4 }, { 3 }}, {{ 1, 2 }, { 3, 4 }}, {{ 1, 3, 4 }, { 2 }}, {{ 1, 3 }, { 2, 4 }}, {{ 1, 4 }, { 2, 3 }}, {{ 1 }, { 2 3, 4 }} }
Approach: The problem can be solved using backtracking to generate and print all the subsets. Follow the steps below to solve the problem:
- Traverse the array and insert elements into any one of the K subsets using the following recurrence relation:Â
Â
PartitionSub(i, K, N)
{
  for (j = 0; j < K; j++) {
   sub[j].push_back(arr[i])
   PartitionSub(i + 1, K, N)
   sub[j].pop_back()
  }
}
- Â
- If K is equal to 0 or K > N, then subsets cannot be generated.
- If count of array elements inserted into K subsets equal to N, then print the elements of the subset.
C++
// C++ program for the above approach Â
#include <bits/stdc++.h> using namespace std; Â
// arr: Store input array // i: Stores current index of arr // N: Stores length of arr // K: Stores count of subsets // nos: Stores count of feasible subsets formed // v: Store K subsets of the given array Â
// Utility function to find all possible // ways to split array into K subsets void PartitionSub( int arr[], int i, Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â int N, int K, int nos, Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â vector<vector< int > >& v) { Â
    // If count of elements in K subsets     // are greater than or equal to N     if (i >= N) { Â
        // If count of subsets         // formed is equal to K         if (nos == K) { Â
            // Print K subsets by splitting             // array into K subsets             for ( int x = 0; x < v.size(); x++) { Â
                cout << "{ " ; Â
                // Print current subset                 for ( int y = 0; y < v[x].size(); y++) {                     cout << v[x][y]; Â
                    // If current element is the last                     // element of the subset                     if (y == v[x].size() - 1) { Â
                        cout << " " ;                     } Â
                    // Otherwise                     else { Â
                        cout << ", " ;                     }                 } Â
                if (x == v.size() - 1) { Â
                    cout << "}" ;                 }                 else { Â
                    cout << "}, " ;                 }             }             cout << endl;         } Â
        return ;     } Â
    for ( int j = 0; j < K; j++) { Â
        // If any subset is occupied,         // then push the element         // in that first         if (v[j].size() > 0) {             v[j].push_back(arr[i]); Â
            // Recursively do the same             // for remaining elements             PartitionSub(arr, i + 1, N, K, nos, v); Â
            // Backtrack             v[j].pop_back();         } Â
        // Otherwise, push it in an empty         // subset and increase the         // subset count by 1         else { Â
            v[j].push_back(arr[i]);             PartitionSub(arr, i + 1, N, K, nos + 1, v);             v[j].pop_back(); Â
            // Break to avoid the case of going in             // other empty subsets, if available,             // and forming the same combination             break ;         }     } } Â
// Function to find all possible ways to // split array into K subsets void partKSubsets( int arr[], int N, int K) { Â
    // Stores K subset by splitting array     // into K subsets     vector<vector< int > > v(K); Â
    // Size of each subset must     // be less than the number of elements     if (K == 0 || K > N) { Â
        cout << "Not Possible" << endl;     }     else { Â
        cout << "The Subset Combinations are: " << endl;         PartitionSub(arr, 0, N, K, 0, v);     } } Â
// Driver Code int main() { Â
    // Given array     int arr[] = { 1, 2, 3, 4 }; Â
    // Given K     int K = 2; Â
    // Size of the array     int N = sizeof (arr) / sizeof (arr[0]); Â
    // Prints all possible     // splits into subsets     partKSubsets(arr, N, K); } |
Java
// Java program for above approach import java.util.*; import java.lang.*; class Gfg { Â
  // arr: Store input array   // i: Stores current index of arr   // N: Stores length of arr   // K: Stores count of subsets   // nos: Stores count of feasible subsets formed   // v: Store K subsets of the given array Â
  // Utility function to find all possible   // ways to split array into K subsets   static void PartitionSub( int arr[], int i,                            int N, int K, int nos,                            ArrayList<ArrayList<Integer>> v)   { Â
    // If count of elements in K subsets     // are greater than or equal to N     if (i >= N)     { Â
      // If count of subsets       // formed is equal to K       if (nos == K)       { Â
        // Print K subsets by splitting         // array into K subsets         for ( int x = 0 ; x < v.size(); x++)         { Â
          System.out.print( "{ " ); Â
          // Print current subset           for ( int y = 0 ; y < v.get(x).size(); y++)           {             System.out.print(v.get(x).get(y)); Â
            // If current element is the last             // element of the subset             if (y == v.get(x).size() - 1 )             {               System.out.print( " " );             } Â
            // Otherwise             else             {               System.out.print( ", " );             }           } Â
          if (x == v.size() - 1 )           {             System.out.print( "}" );           }           else           {             System.out.print( "}, " );           }         }         System.out.println();;       }       return ;     } Â
    for ( int j = 0 ; j < K; j++)     { Â
      // If any subset is occupied,       // then push the element       // in that first       if (v.get(j).size() > 0 )       {         v.get(j).add(arr[i]); Â
        // Recursively do the same         // for remaining elements         PartitionSub(arr, i + 1 , N, K, nos, v); Â
        // Backtrack         v.get(j).remove(v.get(j).size()- 1 );       } Â
      // Otherwise, push it in an empty       // subset and increase the       // subset count by 1       else       { Â
        v.get(j).add(arr[i]);         PartitionSub(arr, i + 1 , N, K, nos + 1 , v);         v.get(j).remove(v.get(j).size()- 1 ); Â
        // Break to avoid the case of going in         // other empty subsets, if available,         // and forming the same combination         break ;       }     }   } Â
  // Function to find all possible ways to   // split array into K subsets   static void partKSubsets( int arr[], int N, int K)   { Â
    // Stores K subset by splitting array     // into K subsets     ArrayList<ArrayList<Integer>> v = new ArrayList<>(); Â
    for ( int i = 0 ; i < K; i++)       v.add( new ArrayList<>()); Â
    // Size of each subset must     // be less than the number of elements     if (K == 0 || K > N)     {       System.out.println( "Not Possible" );     }     else     {       System.out.println( "The Subset Combinations are: " );       PartitionSub(arr, 0 , N, K, 0 , v);     }   } Â
  // Driver function   public static void main (String[] args)   { Â
    // Given array     int arr[] = { 1 , 2 , 3 , 4 }; Â
    // Given K     int K = 2 ; Â
    // Size of the array     int N = arr.length; Â
    // Prints all possible     // splits into subsets     partKSubsets(arr, N, K);   } } Â
// This code is contributed by offbeat |
Python3
# Python 3 program for the above approach Â
# arr: Store input array # i: Stores current index of arr # N: Stores length of arr # K: Stores count of subsets # nos: Stores count of feasible subsets formed # v: Store K subsets of the given array Â
# Utility function to find all possible # ways to split array into K subsets def PartitionSub(arr, i, N, K, nos, v):        # If count of elements in K subsets     # are greater than or equal to N     if (i > = N):                # If count of subsets         # formed is equal to K         if (nos = = K):                        # Print K subsets by splitting             # array into K subsets             for x in range ( len (v)):                 print ( "{ " , end = "") Â
                # Print current subset                 for y in range ( len (v[x])):                     print (v[x][y], end = "") Â
                    # If current element is the last                     # element of the subset                     if (y = = len (v[x]) - 1 ):                         print ( " " , end = "") Â
                    # Otherwise                     else :                         print ( ", " , end = "") Â
                if (x = = len (v) - 1 ):                     print ( "}" , end = "")                                  else :                     print ( "}, " , end = "")             print ( "\n" , end = "")         return     for j in range (K):                # If any subset is occupied,         # then push the element         # in that first         if ( len (v[j]) > 0 ):             v[j].append(arr[i]) Â
            # Recursively do the same             # for remaining elements             PartitionSub(arr, i + 1 , N, K, nos, v)                          # Backtrack             v[j].remove(v[j][ len (v[j]) - 1 ]) Â
        # Otherwise, push it in an empty         # subset and increase the         # subset count by 1         else :             v[j].append(arr[i])             PartitionSub(arr, i + 1 , N, K, nos + 1 , v)             v[j].remove(v[j][ len (v[j]) - 1 ]) Â
            # Break to avoid the case of going in             # other empty subsets, if available,             # and forming the same combination             break Â
# Function to find all possible ways to # split array into K subsets def partKSubsets(arr, N, K):        # Stores K subset by splitting array     # into K subsets     v = [[] for i in range (K)] Â
    # Size of each subset must     # be less than the number of elements     if (K = = 0 or K > N):         print ( "Not Possible" , end = "")     else :         print ( "The Subset Combinations are: " )         PartitionSub(arr, 0 , N, K, 0 , v) Â
# Driver Code if __name__ = = '__main__' :        # Given array     arr =  [ 1 , 2 , 3 , 4 ] Â
    # Given K     K = 2 Â
    # Size of the array     N = len (arr) Â
    # Prints all possible     # splits into subsets     partKSubsets(arr, N, K)          # This code is contributed by bgangwar59. |
C#
// C# program for the above approach using System; using System.Collections.Generic; class GFG { Â
  // arr: Store input array   // i: Stores current index of arr   // N: Stores length of arr   // K: Stores count of subsets   // nos: Stores count of feasible subsets formed   // v: Store K subsets of the given array Â
  // Utility function to find all possible   // ways to split array into K subsets   static void PartitionSub( int []arr, int i,                            int N, int K, int nos,                            List<List< int >>v) { Â
  // If count of elements in K subsets   // are greater than or equal to N   if (i >= N) { Â
    // If count of subsets     // formed is equal to K     if (nos == K) { Â
      // Print K subsets by splitting       // array into K subsets       for ( int x = 0; x < v.Count; x++) { Â
        Console.Write( "{ " ); Â
        // Print current subset         for ( int y = 0; y < v[x].Count; y++) {           Console.Write(v[x][y]); Â
          // If current element is the last           // element of the subset           if (y == v[x].Count - 1) { Â
            Console.Write( " " );           } Â
          // Otherwise           else { Â
            Console.Write( ", " );           }         } Â
        if (x == v.Count - 1) { Â
          Console.Write( "}" );         }         else { Â
          Console.Write( "}, " );         }       }       Console.Write( "\n" );     } Â
    return ;   } Â
  for ( int j = 0; j < K; j++) { Â
    // If any subset is occupied,     // then push the element     // in that first     if (v[j].Count > 0) {       v[j].Add(arr[i]); Â
      // Recursively do the same       // for remaining elements       PartitionSub(arr, i + 1, N, K, nos, v); Â
      // Backtrack       v[j].RemoveAt(v[j].Count - 1);     } Â
    // Otherwise, push it in an empty     // subset and increase the     // subset count by 1     else { Â
      v[j].Add(arr[i]);       PartitionSub(arr, i + 1, N, K, nos + 1, v);       v[j].RemoveAt(v[j].Count - 1); Â
      // Break to avoid the case of going in       // other empty subsets, if available,       // and forming the same combination       break ;     }   } } Â
 // Function to find all possible ways to  // split array into K subsets  static void partKSubsets( int []arr, int N, int K)  { Â
   // Stores K subset by splitting array    // into K subsets    List<List< int > > v = new List<List< int >>();    for ( int i=0;i<K;i++)      v.Add( new List< int >()); Â
   // Size of each subset must    // be less than the number of elements    if (K == 0 || K > N) { Â
     Console.WriteLine( "Not Possible" );    }    else { Â
     Console.WriteLine( "The Subset Combinations are: " );      PartitionSub(arr, 0, N, K, 0, v);    }  } Â
 // Driver Code  public static void Main()  { Â
   // Given array    int []arr = {1, 2, 3, 4}; Â
   // Given K    int K = 2; Â
   // Size of the array    int N = arr.Length; Â
   // Prints all possible    // splits into subsets    partKSubsets(arr, N, K);  } } Â
// This code is contributed by SURENDRA_GANGWAR. |
Javascript
<script>     // Javascript program for above approach          // arr: Store input array     // i: Stores current index of arr     // N: Stores length of arr     // K: Stores count of subsets     // nos: Stores count of feasible subsets formed     // v: Store K subsets of the given array Â
    // Utility function to find all possible     // ways to split array into K subsets     function PartitionSub(arr, i, N, K, nos, v)     { Â
      // If count of elements in K subsets       // are greater than or equal to N       if (i >= N)       { Â
        // If count of subsets         // formed is equal to K         if (nos == K)         { Â
          // Print K subsets by splitting           // array into K subsets           for (let x = 0; x < v.length; x++)           { Â
            document.write( "{ " ); Â
            // Print current subset             for (let y = 0; y < v[x].length; y++)             {               document.write(v[x][y]); Â
              // If current element is the last               // element of the subset               if (y == v[x].length - 1)               {                 document.write( " " );               } Â
              // Otherwise               else               {                 document.write( ", " );               }             } Â
            if (x == v.length - 1)             {               document.write( "}" );             }             else             {               document.write( "}, " );             }           }           document.write( "</br>" );         }         return ;       } Â
      for (let j = 0; j < K; j++)       { Â
        // If any subset is occupied,         // then push the element         // in that first         if (v[j].length > 0)         {           v[j].push(arr[i]); Â
          // Recursively do the same           // for remaining elements           PartitionSub(arr, i + 1, N, K, nos, v); Â
          // Backtrack           v[j].pop();         } Â
        // Otherwise, push it in an empty         // subset and increase the         // subset count by 1         else         { Â
          v[j].push(arr[i]);           PartitionSub(arr, i + 1, N, K, nos + 1, v);           v[j].pop(); Â
          // Break to avoid the case of going in           // other empty subsets, if available,           // and forming the same combination           break ;         }       }     } Â
    // Function to find all possible ways to     // split array into K subsets     function partKSubsets(arr, N, K)     { Â
      // Stores K subset by splitting array       // into K subsets       let v = []; Â
      for (let i = 0; i < K; i++)         v.push([]); Â
      // Size of each subset must       // be less than the number of elements       if (K == 0 || K > N)       {         document.write( "Not Possible" + "</br>" );       }       else       {         document.write( "The Subset Combinations are: " + "</br>" );         PartitionSub(arr, 0, N, K, 0, v);       }     }          // Given array     let arr = [ 1, 2, 3, 4 ];       // Given K     let K = 2;       // Size of the array     let N = arr.length;       // Prints all possible     // splits into subsets     partKSubsets(arr, N, K); Â
// This code is contributed by decode2207. </script> |
The Subset Combinations are: { 1, 2, 3 }, { 4 } { 1, 2, 4 }, { 3 } { 1, 2 }, { 3, 4 } { 1, 3, 4 }, { 2 } { 1, 3 }, { 2, 4 } { 1, 4 }, { 2, 3 } { 1 }, { 2, 3, 4 }
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!
[…] Approach: The simplest approach is, split the array into K subsets for every integer K less than or equal to N, and then check if all the subsets of the array satisfy […]