Given an array of integers arr[], The task is to find all its subsets. The subset can not contain duplicate elements, so any repeated subset should be considered only once in the output.
Examples:
Input: S = {1, 2, 2}
Output: {}, {1}, {2}, {1, 2}, {2, 2}, {1, 2, 2}
Explanation: The total subsets of given set are – {}, {1}, {2}, {2}, {1, 2}, {1, 2}, {2, 2}, {1, 2, 2}
Here {2} and {1, 2} are repeated twice so they are considered only once in the output
Input: S = {1, 2}
Output: {}, {1}, {2}, {1, 2}
Explanation: The total subsets of given set are – {}, {1}, {2}, {1, 2}
BRUTE METHOD:
Intuition:
- We do this problem by using the backtracking approach.
- we declare a arraylist to store all the subsets generated.
- We sort the array in order to skip repeated subsets as it should be unique.
- then we pick a particular element or not pick from the array and we generate the subsets.
- atlast we add it in the final list and return it.
Implementation:
C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void findSubsets( int ind, vector< int >& nums, vector< int >& ds, vector<vector< int >>& ansList) {
ansList.push_back(ds);
for ( int i = ind; i < nums.size(); i++) {
if (i != ind && nums[i] == nums[i - 1])
continue ;
ds.push_back(nums[i]);
findSubsets(i + 1, nums, ds, ansList);
ds.pop_back();
}
}
vector<vector< int >> AllSubsets( int arr[], int n) {
vector< int > nums(arr, arr + n);
vector< int > ds;
sort(nums.begin(), nums.end());
vector<vector< int >> ansList;
findSubsets(0, nums, ds, ansList);
return ansList;
}
int main() {
int set[] = { 10, 12, 12 };
vector<vector< int >> subsets = AllSubsets(set, 3);
for ( auto subset : subsets) {
cout << "[" ;
for ( int i = 0; i < subset.size(); i++) {
cout << subset[i];
if (i < subset.size() - 1) {
cout << ", " ;
}
}
cout << "], " ;
}
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
public static void
findSubsets( int ind, int [] nums, ArrayList<Integer> ds,
ArrayList<ArrayList<Integer> > ansList)
{
ansList.add( new ArrayList<>(ds));
for ( int i = ind; i < nums.length; i++) {
if (i != ind && nums[i] == nums[i - 1 ])
continue ;
ds.add(nums[i]);
findSubsets(i + 1 , nums, ds, ansList);
ds.remove(ds.size() - 1 );
}
}
public static ArrayList<ArrayList<Integer> >
AllSubsets( int arr[], int n)
{
Arrays.sort(arr);
ArrayList<ArrayList<Integer> > ansList
= new ArrayList<>();
findSubsets( 0 , arr, new ArrayList<>(), ansList);
return ansList;
}
public static void main(String[] args)
{
int [] set = { 10 , 12 , 12 };
System.out.println(AllSubsets(set, 3 ));
}
}
|
Python3
def find_subsets(ind, nums, ds, ans_list):
ans_list.append( list (ds))
for i in range (ind, len (nums)):
if i ! = ind and nums[i] = = nums[i - 1 ]:
continue
ds.append(nums[i])
find_subsets(i + 1 , nums, ds, ans_list)
ds.pop()
def all_subsets(arr):
nums = sorted (arr)
ans_list = []
find_subsets( 0 , nums, [], ans_list)
return ans_list
if __name__ = = "__main__" :
set = [ 10 , 12 , 12 ]
subsets = all_subsets( set )
for subset in subsets:
print (subset, end = ", " )
|
C#
using System;
using System.Collections.Generic;
public class GFG
{
static void FindSubsets( int ind, int [] nums, List< int > ds, List<List< int >> ansList)
{
ansList.Add( new List< int >(ds));
for ( int i = ind; i < nums.Length; i++)
{
if (i != ind && nums[i] == nums[i - 1])
continue ;
ds.Add(nums[i]);
FindSubsets(i + 1, nums, ds, ansList);
ds.RemoveAt(ds.Count - 1);
}
}
static List<List< int >> AllSubsets( int [] arr)
{
Array.Sort(arr);
List<List< int >> ansList = new List<List< int >>();
FindSubsets(0, arr, new List< int >(), ansList);
return ansList;
}
public static void Main()
{
int [] set = { 10, 12, 12 };
List<List< int >> subsets = AllSubsets( set );
foreach (List< int > subset in subsets)
{
Console.Write( "[" );
for ( int i = 0; i < subset.Count; i++)
{
Console.Write(subset[i]);
if (i < subset.Count - 1)
{
Console.Write( ", " );
}
}
Console.Write( "], " );
}
}
}
|
Javascript
function findSubsets(ind, nums, ds, ansList) {
ansList.push([...ds]);
for (let i = ind; i < nums.length; i++) {
if (i !== ind && nums[i] === nums[i - 1]) {
continue ;
}
ds.push(nums[i]);
findSubsets(i + 1, nums, ds, ansList);
ds.pop();
}
}
function allSubsets(arr) {
const nums = arr.slice().sort((a, b) => a - b);
const ansList = [];
findSubsets(0, nums, [], ansList);
return ansList;
}
const set = [10, 12, 12];
const subsets = allSubsets(set);
for (const subset of subsets) {
console.log(subset);
}
|
Output[[], [10], [10, 12], [10, 12, 12], [12], [12, 12]]
Time Complexity: O(2^N * N) since we are generating every subset
Auxiliary Space: O(2^N)
Prerequisite: Power Set
Approach: Below is the idea to solve the problem:
The idea is to use a bit-mask pattern to generate all the combinations as discussed in post. To avoid printing duplicate subsets construct a string out of given subset such that subsets having similar elements will result in same string. Maintain a list of such unique strings and finally decode all such string to print its individual elements.
Illustration :
S = {1, 2, 2}
The binary digits from 0 to 7 are
0 –> 000 –> number formed with no setbits –> { }
1 –> 001 –> number formed with setbit at position 0 –> { 1 }
2 –> 010 –> number formed with setbit at position 1 –> { 2 }
3 –> 011 –> number formed with setbit at position 0 and 1 –> { 1 , 2 }
4 –> 100 –> number formed with setbit at position 2 –> { 2 }
5 –> 101 –> number formed with setbit at position 0 and 2 –> { 1 , 2}
6 –> 110 –> number formed with setbit at position 1 and 2 –> { 2 , 2}
7 –> 111 –> number formed with setbit at position 0 , 1 and 2 –> {1 , 2 , 2}
After removing duplicates final result will be { }, { 1 }, { 2 }, { 1 , 2 }, { 2 , 2 }, { 1 , 2 , 2}
Note: This method will only work on sorted arrays.
Follow the below steps to Implement the idea:
- Initialize a variable pow_set_size as 2 raise to size of array and a vector of vector ans to store all subsets.
- Iterate over all bitmasks from 0 to pow_set_size – 1.
- For every bitmask include the elements of array of indices where bits are set into a subset vector.
- If this subset doesn’t already exist then push the subset in the ans vector.
- Return ans.
Below is the implementation of the above approach:
C++14
#include <bits/stdc++.h>
using namespace std;
vector<vector< int > > findPowerSet(vector< int >& nums)
{
int bits = nums.size();
unsigned int pow_set_size = pow (2, bits);
sort(nums.begin(), nums.end());
vector<vector< int > > ans;
vector<string> list;
for ( int counter = 0; counter < pow_set_size;
counter++) {
vector< int > subset;
string temp = "" ;
for ( int j = 0; j < bits; j++) {
if (counter & (1 << j)) {
subset.push_back(nums[j]);
temp += to_string(nums[j]) + '$' ;
}
}
if (find(list.begin(), list.end(), temp)
== list.end()) {
ans.push_back(subset);
list.push_back(temp);
}
}
return ans;
}
int main()
{
vector< int > arr{ 10, 12, 12 };
vector<vector< int > > power_set = findPowerSet(arr);
for ( int i = 0; i < power_set.size(); i++) {
for ( int j = 0; j < power_set[i].size(); j++)
cout << power_set[i][j] << " " ;
cout << endl;
}
return 0;
}
|
Java
import java.io.*;
import java.util.*;
public class GFG {
static void printPowerSet( int [] set, int set_size)
{
ArrayList<String> subset = new ArrayList<String>();
long pow_set_size = ( long )Math.pow( 2 , set_size);
int counter, j;
for (counter = 0 ; counter < pow_set_size;
counter++) {
String temp = "" ;
for (j = 0 ; j < set_size; j++) {
if ((counter & ( 1 << j)) > 0 )
temp
+= (Integer.toString(set[j]) + '$' );
}
if (!subset.contains(temp)
&& temp.length() > 0 ) {
subset.add(temp);
}
}
for (String s : subset) {
s = s.replace( '$' , ' ' );
System.out.println(s);
}
}
public static void main(String[] args)
{
int [] set = { 10 , 12 , 12 };
printPowerSet(set, 3 );
}
}
|
Python3
def printPowerSet(arr, n):
_list = []
for i in range ( 2 * * n):
subset = ""
for j in range (n):
if (i & ( 1 << j)) ! = 0 :
subset + = str (arr[j]) + "|"
if subset not in _list and len (subset) > 0 :
_list.append(subset)
for subset in _list:
arr = subset.split( '|' )
for string in arr:
print (string, end = " " )
print ()
if __name__ = = '__main__' :
arr = [ 10 , 12 , 12 ]
n = len (arr)
printPowerSet(arr, n)
|
C#
using System;
using System.Collections.Generic;
public class GFG {
static void printPowerSet( int [] set , int set_size)
{
List< string > subset = new List< string >();
long pow_set_size = ( long )Math.Pow(2, set_size);
int counter, j;
for (counter = 0; counter < pow_set_size;
counter++) {
string temp = "" ;
for (j = 0; j < set_size; j++) {
if ((counter & (1 << j)) > 0)
temp
+= (Convert.ToString( set [j]) + ' ' );
}
if (!subset.Contains(temp) && temp.Length > 0) {
subset.Add(temp);
}
}
foreach ( string s in subset)
{
s.Replace( '$' , ' ' );
Console.WriteLine(s);
}
}
public static void Main( string [] args)
{
int [] set = { 10, 12, 12 };
printPowerSet( set , 3);
}
}
|
Javascript
<script>
const findPowerSet = (nums) => {
let bits = nums.length;
let pow_set_size = Math.pow(2, bits);
nums.sort();
let ans = [];
let list = [];
for (let counter = 0; counter < pow_set_size; counter++) {
let subset = [];
let temp = "" ;
for (let j = 0; j < bits; j++) {
if (counter & (1 << j)) {
subset.push(nums[j]);
temp += nums[j].toString() + '$' ;
}
}
if (list.indexOf(temp) == -1) {
ans.push(subset);
list.push(temp);
}
}
return ans;
}
let arr = [10, 12, 12];
let power_set = findPowerSet(arr);
for (let i = 0; i < power_set.length; i++) {
for (let j = 0; j < power_set[i].length; j++)
document.write(`${power_set[i][j]} `);
document.write( "<br/>" );
}
</script>
|
Output10
12
10 12
12 12
10 12 12
Time Complexity: O(N*2N)
Auxiliary Space: O(N*N)
Analysis:
If
is the total number of steps in the code, then the loop to generate all binary combinations runs till, and then the inner loop run till log(i).
Hence,
, Raising to the power of two on both sides
Using log on both sides and applying Sterling’s approximation,

Hence the time complexity is 
Find all distinct subsets of a given set using BitMasking Approach using Backtracking
Refer to the article https://www.geeksforgeeks.org/backtracking-to-find-all-subsets/ to solve the problem using the backtracking approach.
This article is contributed by Aditya Goel. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.GeeksforGeeks.org or mail your article to contribute@GeeksforGeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.