Print all subsets of given size of a set
Generate all possible subsets of size r of the given array with distinct elements.
Examples:
Input : arr[] = {1, 2, 3, 4} r = 2 Output : 1 2 1 3 1 4 2 3 2 4 3 4 Input : arr[] = {10, 20, 30, 40, 50} r = 3 Output : 10 20 30 10 20 40 10 20 50 10 30 40 10 30 50 10 40 50 20 30 40 20 30 50 20 40 50 30 40 50
This problem is the same Print all possible combinations of r elements in a given array of size n.
The idea here is similar to Subset Sum Problem. We, one by one, consider every element of the input array, and recur for two cases:
- The element is included in the current combination (We put the element in data[] and increase the next available index in data[])
- The element is excluded in the current combination (We do not put the element in and do not change the index)
When the number of elements in data[] becomes equal to r (size of a combination), we print it.
This method is mainly based on Pascal’s Identity, i.e. ncr = n-1cr + n-1cr-1
Implementation:
C++
// C++ Program to print all combination of size r in // an array of size n #include <iostream> using namespace std; void combinationUtil( int arr[], int n, int r, int index, int data[], int i); // The main function that prints all combinations of // size r in arr[] of size n. This function mainly // uses combinationUtil() void printCombination( int arr[], int n, int r) { // A temporary array to store all combination // one by one int data[r]; // Print all combination using temporary array 'data[]' combinationUtil(arr, n, r, 0, data, 0); } /* arr[] ---> Input Array n ---> Size of input array r ---> Size of a combination to be printed index ---> Current index in data[] data[] ---> Temporary array to store current combination i ---> index of current element in arr[] */ void combinationUtil( int arr[], int n, int r, int index, int data[], int i) { // Current combination is ready, print it if (index == r) { for ( int j = 0; j < r; j++) cout << " " << data[j]; cout << "\n" ; return ; } // When no more elements are there to put in data[] if (i >= n) return ; // current is included, put next at next location data[index] = arr[i]; combinationUtil(arr, n, r, index + 1, data, i + 1); // current is excluded, replace it with next // (Note that i+1 is passed, but index is not // changed) combinationUtil(arr, n, r, index, data, i + 1); } // Driver program to test above functions int main() { int arr[] = { 10, 20, 30, 40, 50 }; int r = 3; int n = sizeof (arr) / sizeof (arr[0]); printCombination(arr, n, r); return 0; } // This code is contributed by shivanisinghss2110 |
C
// C++ Program to print all combination of size r in // an array of size n #include <stdio.h> void combinationUtil( int arr[], int n, int r, int index, int data[], int i); // The main function that prints all combinations of // size r in arr[] of size n. This function mainly // uses combinationUtil() void printCombination( int arr[], int n, int r) { // A temporary array to store all combination // one by one int data[r]; // Print all combination using temporary array 'data[]' combinationUtil(arr, n, r, 0, data, 0); } /* arr[] ---> Input Array n ---> Size of input array r ---> Size of a combination to be printed index ---> Current index in data[] data[] ---> Temporary array to store current combination i ---> index of current element in arr[] */ void combinationUtil( int arr[], int n, int r, int index, int data[], int i) { // Current combination is ready, print it if (index == r) { for ( int j = 0; j < r; j++) printf ( "%d " , data[j]); printf ( "\n" ); return ; } // When no more elements are there to put in data[] if (i >= n) return ; // current is included, put next at next location data[index] = arr[i]; combinationUtil(arr, n, r, index + 1, data, i + 1); // current is excluded, replace it with next // (Note that i+1 is passed, but index is not // changed) combinationUtil(arr, n, r, index, data, i + 1); } // Driver program to test above functions int main() { int arr[] = { 10, 20, 30, 40, 50 }; int r = 3; int n = sizeof (arr) / sizeof (arr[0]); printCombination(arr, n, r); return 0; } |
Java
// Java program to print all combination of size // r in an array of size n import java.io.*; class Permutation { /* arr[] ---> Input Array data[] ---> Temporary array to store current combination start & end ---> Starting and Ending indexes in arr[] index ---> Current index in data[] r ---> Size of a combination to be printed */ static void combinationUtil( int arr[], int n, int r, int index, int data[], int i) { // Current combination is ready to be printed, // print it if (index == r) { for ( int j = 0 ; j < r; j++) System.out.print(data[j] + " " ); System.out.println( "" ); return ; } // When no more elements are there to put in data[] if (i >= n) return ; // current is included, put next at next // location data[index] = arr[i]; combinationUtil(arr, n, r, index + 1 , data, i + 1 ); // current is excluded, replace it with // next (Note that i+1 is passed, but // index is not changed) combinationUtil(arr, n, r, index, data, i + 1 ); } // The main function that prints all combinations // of size r in arr[] of size n. This function // mainly uses combinationUtil() static void printCombination( int arr[], int n, int r) { // A temporary array to store all combination // one by one int data[] = new int [r]; // Print all combination using temporary // array 'data[]' combinationUtil(arr, n, r, 0 , data, 0 ); } /* Driver function to check for above function */ public static void main(String[] args) { int arr[] = { 10 , 20 , 30 , 40 , 50 }; int r = 3 ; int n = arr.length; printCombination(arr, n, r); } } /* This code is contributed by Devesh Agrawal */ |
Python3
# Python3 program to print all # subset combination of n # element in given set of r element . # arr[] ---> Input Array # data[] ---> Temporary array to # store current combination # start & end ---> Starting and Ending # indexes in arr[] # index ---> Current index in data[] # r ---> Size of a combination # to be printed def combinationUtil(arr, n, r, index, data, i): # Current combination is # ready to be printed, # print it if (index = = r): for j in range (r): print (data[j], end = " " ) print ( " " ) return # When no more elements # are there to put in data[] if (i > = n): return # current is included, # put next at next # location data[index] = arr[i] combinationUtil(arr, n, r, index + 1 , data, i + 1 ) # current is excluded, # replace it with # next (Note that i+1 # is passed, but index # is not changed) combinationUtil(arr, n, r, index, data, i + 1 ) # The main function that # prints all combinations # of size r in arr[] of # size n. This function # mainly uses combinationUtil() def printcombination(arr, n, r): # A temporary array to # store all combination # one by one data = list ( range (r)) # Print all combination # using temporary # array 'data[]' combinationUtil(arr, n, r, 0 , data, 0 ) # Driver Code arr = [ 10 , 20 , 30 , 40 , 50 ] r = 3 n = len (arr) printcombination(arr, n, r) # This code is contributed # by Ambuj sahu |
C#
// C# program to print all combination // of size r in an array of size n using System; class GFG { /* arr[] ---> Input Array data[] ---> Temporary array to store current combination start & end ---> Starting and Ending indexes in arr[] index ---> Current index in data[] r ---> Size of a combination to be printed */ static void combinationUtil( int []arr, int n, int r, int index, int []data, int i) { // Current combination is ready to // be printed, print it if (index == r) { for ( int j = 0; j < r; j++) Console.Write(data[j] + " " ); Console.WriteLine( "" ); return ; } // When no more elements are there // to put in data[] if (i >= n) return ; // current is included, put next // at next location data[index] = arr[i]; combinationUtil(arr, n, r, index + 1, data, i + 1); // current is excluded, replace // it with next (Note that i+1 // is passed, but index is not // changed) combinationUtil(arr, n, r, index, data, i + 1); } // The main function that prints all // combinations of size r in arr[] of // size n. This function mainly uses // combinationUtil() static void printCombination( int []arr, int n, int r) { // A temporary array to store all // combination one by one int []data = new int [r]; // Print all combination using // temporary array 'data[]' combinationUtil(arr, n, r, 0, data, 0); } /* Driver function to check for above function */ public static void Main() { int []arr = { 10, 20, 30, 40, 50 }; int r = 3; int n = arr.Length; printCombination(arr, n, r); } } // This code is contributed by vt_m. |
PHP
<?php // Program to print all combination of // size r in an array of size n // The main function that prints all // combinations of size r in arr[] of // size n. This function mainly uses // combinationUtil() function printCombination( $arr , $n , $r ) { // A temporary array to store all // combination one by one $data = array (); // Print all combination using // temporary array 'data[]' combinationUtil( $arr , $n , $r , 0, $data , 0); } /* arr[] ---> Input Array n ---> Size of input array r ---> Size of a combination to be printed index ---> Current index in data[] data[] ---> Temporary array to store current combination i ---> index of current element in arr[] */ function combinationUtil( $arr , $n , $r , $index , $data , $i ) { // Current combination is ready, print it if ( $index == $r ) { for ( $j = 0; $j < $r ; $j ++) echo $data [ $j ], " " ; echo "\n" ; return ; } // When no more elements are there to // put in data[] if ( $i >= $n ) return ; // current is included, put next at // next location $data [ $index ] = $arr [ $i ]; combinationUtil( $arr , $n , $r , $index + 1, $data , $i + 1); // current is excluded, replace it with // next (Note that i+1 is passed, but // index is not changed) combinationUtil( $arr , $n , $r , $index , $data , $i + 1); } // Driver program to test above functions $arr = array ( 10, 20, 30, 40, 50 ); $r = 3; $n = count ( $arr ); printCombination( $arr , $n , $r ); // This code is contributed by anuj_67. ?> |
Javascript
<script> // Javascript program to print all combination // of size r in an array of size n /* arr[] ---> Input Array data[] ---> Temporary array to store current combination start & end ---> Starting and Ending indexes in arr[] index ---> Current index in data[] r ---> Size of a combination to be printed */ function combinationUtil(arr, n, r, index, data, i) { // Current combination is ready to // be printed, print it if (index == r) { for (let j = 0; j < r; j++) document.write(data[j] + " " ); document.write( "</br>" ); return ; } // When no more elements are there // to put in data[] if (i >= n) return ; // current is included, put next // at next location data[index] = arr[i]; combinationUtil(arr, n, r, index + 1, data, i + 1); // current is excluded, replace // it with next (Note that i+1 // is passed, but index is not // changed) combinationUtil(arr, n, r, index, data, i + 1); } // The main function that prints all // combinations of size r in arr[] of // size n. This function mainly uses // combinationUtil() function printCombination(arr, n, r) { // A temporary array to store all // combination one by one let data = new Array(r); data.fill(0); // Print all combination using // temporary array 'data[]' combinationUtil(arr, n, r, 0, data, 0); } let arr = [ 10, 20, 30, 40, 50 ]; let r = 3; let n = arr.length; printCombination(arr, n, r); </script> |
10 20 30 10 20 40 10 20 50 10 30 40 10 30 50 10 40 50 20 30 40 20 30 50 20 40 50 30 40 50
Time complexity of this algorithm is O(n*r). The outer loop runs n times and the inner loop runs r times.
Auxiliary Space: O(r), the space complexity is O(r) because we are creating a temporary array of size r and storing the combinations
in it.
Approach 2: Using DP
The given program generates combinations of size r from an array of size n using a recursive approach. It does not use dynamic programming (DP) explicitly. However, dynamic programming can be applied to optimize the solution by avoiding redundant computations.
To implement a DP approach, we can use a 2D table to store the intermediate results and avoid recomputing the same combinations. Here’s an updated version of the program that incorporates dynamic programming:
C++
#include <iostream> #include <vector> using namespace std; // Function to print all combinations of size r // using a dynamic programming approach void printCombination( int arr[], int n, int r) { vector<vector< int >> dp(n + 1, vector< int >(r + 1, 0)); // Calculate the combinations using dynamic programming for ( int i = 0; i <= n; i++) { for ( int j = 0; j <= min(i, r); j++) { if (j == 0 || j == i) dp[i][j] = 1; else dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]; } } // Print the combinations for ( int i = 0; i < dp[n].size(); i++) { if (dp[n][i] == 0) break ; for ( int j = 0; j < dp[n][i]; j++) { cout << arr[i] << " " ; } cout << endl; } } // Driver program to test above functions int main() { int arr[] = { 10, 20, 30, 40, 50 }; int r = 3; int n = sizeof (arr) / sizeof (arr[0]); printCombination(arr, n, r); return 0; } |
10 20 20 20 20 20 30 30 30 30 30 30 30 30 30 30 40 40 40 40 40 40 40 40 40 40
Time complexity of this algorithm is O(n*r).The outer loop runs n times and the inner loop runs r times.
Auxiliary Space: O(n*r).
Another Approach(using BitMasking):
Follow the below steps to solve the above problem:
1) Generate all possible binary numbers with a length equal to the number of elements in the set. Each binary number will represent a potential subset.
2) Iterate through each binary number from 0 to 2^N – 1, where N is the number of elements in the set. This represents all possible subsets of the set.
3) For each binary number, check the number of set bits(1s). If the count of set bits is equal to the desired subset size, consider it as a valid subset.
4) To extract the elements of the subset, iterate through the bits of the binary number. If a bit is set (1), include the corresponding element from the set in the subset.
5) Print the desired output.
Below is the implementation of above approach:
C++
#include <bits/stdc++.h> using namespace std; void printSubset( int arr[], int subset[], int r) { for ( int i = 0; i < r; i++) cout << subset[i] << " " ; cout << endl; } void printCombination( int arr[], int n, int r) { int totalSubsets = 1 << n; // Total number of subsets is 2^n for ( int bitmask = 0; bitmask < totalSubsets; bitmask++) { // Count the number of set bits in the bitmask int count = 0; int temp = bitmask; while (temp > 0) { count += temp & 1; temp >>= 1; } if (count == r) { int subset[r]; int index = 0; for ( int i = 0; i < n; i++) { if (bitmask & (1 << i)) subset[index++] = arr[i]; } printSubset(arr, subset, r); } } } int main() { int arr[] = {10, 20, 30, 40, 50}; int r = 3; int n = sizeof (arr) / sizeof (arr[0]); printCombination(arr, n, r); return 0; } // This code is contributed by Yash Agarwal(yashagarwal2852002) |
10 20 30 10 20 40 10 30 40 20 30 40 10 20 50 10 30 50 20 30 50 10 40 50 20 40 50 30 40 50
Time Complexity: O(2^n), where n is the number of elements in the given array.
Auxiliary Space: O(n+r)
Refer to the post below for more solutions and ideas to handle duplicates in the input array.
Print all possible combinations of r elements in a given array of size n.
This article is contributed by Dhiman Mayank. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please Login to comment...