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++ 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 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 |
# 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# 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. |
<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 }