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++
#include <iostream>
using namespace std;
void combinationUtil( int arr[], int n, int r,
int index, int data[], int i);
void printCombination( int arr[], int n, int r)
{
int data[r];
combinationUtil(arr, n, r, 0, data, 0);
}
void combinationUtil( int arr[], int n, int r, int index,
int data[], int i)
{
if (index == r) {
for ( int j = 0; j < r; j++)
cout << " " << data[j];
cout << "\n" ;
return ;
}
if (i >= n)
return ;
data[index] = arr[i];
combinationUtil(arr, n, r, index + 1, data, i + 1);
combinationUtil(arr, n, r, index, data, i + 1);
}
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;
}
|
C
#include <stdio.h>
void combinationUtil( int arr[], int n, int r,
int index, int data[], int i);
void printCombination( int arr[], int n, int r)
{
int data[r];
combinationUtil(arr, n, r, 0, data, 0);
}
void combinationUtil( int arr[], int n, int r, int index,
int data[], int i)
{
if (index == r) {
for ( int j = 0; j < r; j++)
printf ( "%d " , data[j]);
printf ( "\n" );
return ;
}
if (i >= n)
return ;
data[index] = arr[i];
combinationUtil(arr, n, r, index + 1, data, i + 1);
combinationUtil(arr, n, r, index, data, i + 1);
}
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
import java.io.*;
class Permutation {
static void combinationUtil( int arr[], int n, int r,
int index, int data[], int i)
{
if (index == r) {
for ( int j = 0 ; j < r; j++)
System.out.print(data[j] + " " );
System.out.println( "" );
return ;
}
if (i >= n)
return ;
data[index] = arr[i];
combinationUtil(arr, n, r, index + 1 ,
data, i + 1 );
combinationUtil(arr, n, r, index, data, i + 1 );
}
static void printCombination( int arr[], int n, int r)
{
int data[] = new int [r];
combinationUtil(arr, n, r, 0 , data, 0 );
}
public static void main(String[] args)
{
int arr[] = { 10 , 20 , 30 , 40 , 50 };
int r = 3 ;
int n = arr.length;
printCombination(arr, n, r);
}
}
|
Python3
def combinationUtil(arr, n, r,
index, data, i):
if (index = = r):
for j in range (r):
print (data[j], end = " " )
print ( " " )
return
if (i > = n):
return
data[index] = arr[i]
combinationUtil(arr, n, r,
index + 1 , data, i + 1 )
combinationUtil(arr, n, r, index,
data, i + 1 )
def printcombination(arr, n, r):
data = list ( range (r))
combinationUtil(arr, n, r,
0 , data, 0 )
arr = [ 10 , 20 , 30 , 40 , 50 ]
r = 3
n = len (arr)
printcombination(arr, n, r)
|
C#
using System;
class GFG {
static void combinationUtil( int []arr,
int n, int r, int index,
int []data, int i)
{
if (index == r)
{
for ( int j = 0; j < r; j++)
Console.Write(data[j] + " " );
Console.WriteLine( "" );
return ;
}
if (i >= n)
return ;
data[index] = arr[i];
combinationUtil(arr, n, r, index + 1,
data, i + 1);
combinationUtil(arr, n, r, index,
data, i + 1);
}
static void printCombination( int []arr,
int n, int r)
{
int []data = new int [r];
combinationUtil(arr, n, r, 0, data, 0);
}
public static void Main()
{
int []arr = { 10, 20, 30, 40, 50 };
int r = 3;
int n = arr.Length;
printCombination(arr, n, r);
}
}
|
Javascript
<script>
function combinationUtil(arr, n, r, index, data, i)
{
if (index == r)
{
for (let j = 0; j < r; j++)
document.write(data[j] + " " );
document.write( "</br>" );
return ;
}
if (i >= n)
return ;
data[index] = arr[i];
combinationUtil(arr, n, r, index + 1,
data, i + 1);
combinationUtil(arr, n, r, index,
data, i + 1);
}
function printCombination(arr, n, r)
{
let data = new Array(r);
data.fill(0);
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>
|
PHP
<?php
function printCombination( $arr , $n , $r )
{
$data = array ();
combinationUtil( $arr , $n , $r , 0, $data , 0);
}
function combinationUtil( $arr , $n , $r , $index ,
$data , $i )
{
if ( $index == $r ) {
for ( $j = 0; $j < $r ; $j ++)
echo $data [ $j ], " " ;
echo "\n" ;
return ;
}
if ( $i >= $n )
return ;
$data [ $index ] = $arr [ $i ];
combinationUtil( $arr , $n , $r , $index + 1,
$data , $i + 1);
combinationUtil( $arr , $n , $r , $index ,
$data , $i + 1);
}
$arr = array ( 10, 20, 30, 40, 50 );
$r = 3;
$n = count ( $arr );
printCombination( $arr , $n , $r );
?>
|
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
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;
void printCombination( int arr[], int n, int r)
{
vector<vector< int >> dp(n + 1, vector< int >(r + 1, 0));
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];
}
}
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;
}
}
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
import java.util.ArrayList;
import java.util.List;
public class GFG {
public static void printCombination( int [] arr, int n, int r) {
List<List<Integer>> dp = new ArrayList<>(n + 1 );
for ( int i = 0 ; i <= n; i++) {
dp.add( new ArrayList<>(r + 1 ));
for ( int j = 0 ; j <= r; j++) {
dp.get(i).add( 0 );
}
}
for ( int i = 0 ; i <= n; i++) {
for ( int j = 0 ; j <= Math.min(i, r); j++) {
if (j == 0 || j == i) {
dp.get(i).set(j, 1 );
} else {
int val1 = dp.get(i - 1 ).get(j - 1 );
int val2 = dp.get(i - 1 ).get(j);
dp.get(i).set(j, val1 + val2);
}
}
}
for ( int i = 0 ; i < dp.get(n).size(); i++) {
int count = dp.get(n).get(i);
if (count == 0 ) {
break ;
}
for ( int j = 0 ; j < count; j++) {
System.out.print(arr[i] + " " );
}
System.out.println();
}
}
public static void main(String[] args) {
int [] arr = { 10 , 20 , 30 , 40 , 50 };
int r = 3 ;
int n = arr.length;
printCombination(arr, n, r);
}
}
|
Python3
def print_combination(arr, n, r):
dp = [[ 0 ] * (r + 1 ) for _ in range (n + 1 )]
for i in range (n + 1 ):
for j in range ( min (i, r) + 1 ):
if j = = 0 or j = = i:
dp[i][j] = 1
else :
dp[i][j] = dp[i - 1 ][j - 1 ] + dp[i - 1 ][j]
for i in range ( len (dp[n])):
if dp[n][i] = = 0 :
break
for j in range (dp[n][i]):
print (arr[i], end = " " )
print ()
if __name__ = = "__main__" :
arr = [ 10 , 20 , 30 , 40 , 50 ]
r = 3
n = len (arr)
print_combination(arr, n, r)
|
Output10
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;
for ( int bitmask = 0; bitmask < totalSubsets; 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;
}
|
C#
using System;
class GFG
{
static void PrintSubset( int [] arr, int [] subset, int r)
{
for ( int i = 0; i < r; i++)
Console.Write(subset[i] + " " );
Console.WriteLine();
}
static void PrintCombination( int [] arr, int n, int r)
{
int totalSubsets = 1 << n;
for ( int bitmask = 0; bitmask < totalSubsets; bitmask++)
{
int count = 0;
int temp = bitmask;
while (temp > 0)
{
count += temp & 1;
temp >>= 1;
}
if (count == r)
{
int [] subset = new int [r];
int index = 0;
for ( int i = 0; i < n; i++)
{
if ((bitmask & (1 << i)) > 0)
subset[index++] = arr[i];
}
PrintSubset(arr, subset, r);
}
}
}
static void Main()
{
int [] arr = { 10, 20, 30, 40, 50 };
int r = 3;
int n = arr.Length;
PrintCombination(arr, n, r);
}
}
|
Output10 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.