Skip to content
Related Articles

Related Articles

Improve Article

Print all possible ways to split an array into K subsets

  • Difficulty Level : Medium
  • Last Updated : 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 = 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:



  1. 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()

   }

}

  1.  
  2. If K is equal to 0 or K > N, then subsets cannot be generated.
  3. 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 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 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 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 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 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>
Output
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 }

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :