Print all possible ways to split an array into K subsets

21 Jul, 2021
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 = 2Output: { {{ 1, 2 }, { 3 }}, {{ 1, 3 }, { 2 }}, {{ 1 }, { 2, 3 }}}.
Input: arr[] = { 1, 2, 3, 4 }, K = 2Output: { {{ 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:  
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.
 
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++
Java
Python3
C#
Javascript
// 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 subsetsvoid 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 to find all possible ways to// split array into K subsetsvoid 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 Codeint 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 program for above approachimport 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 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
# 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 subsetsdef 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 to find all possible ways to# split array into K subsetsdef 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 Codeif __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# program for the above approachusing 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 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.
<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 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 }
bgangwar59
SURENDRA_GANGWAR
offbeat
gulshankumarar231
decode2207
subset
Technical Scripter 2020
Arrays
Backtracking
Recursion
Stack
Technical Scripter
Arrays
Recursion
Stack
subset
Backtracking
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Maximum and minimum of an array using minimum number of comparisons
Top 50 Array Coding Problems for Interviews
Multidimensional Arrays in Java
Stack Data Structure (Introduction and Program)
Linear Search
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
N Queen Problem | Backtracking-3
The Knight's tour problem | Backtracking-1
Rat in a Maze | Backtracking-2
Backtracking | Introduction