Open In App
Related Articles

# Find all distinct subsets of a given set using BitMasking Approach

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}

Recommended Practice

## BRUTE METHOD:

Intuition:

1. We do this problem by using the backtracking approach.
2. we declare a arraylist to store all the subsets generated.
3. We  sort the array in order to skip repeated subsets as it should be unique.
4. then we pick a particular element or not pick from the array and we generate the subsets.
5. atlast we add it in the final list and return it.

Implementation:

## C++

 // C++ program to find all subsets of given set. Any// repeated subset is considered only once in the output#include #include #include using namespace std; void findSubsets(int ind, vector<int>& nums, vector<int>& ds, vector>& 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> AllSubsets(int arr[], int n) {    vector<int> nums(arr, arr + n);    vector<int> ds;    sort(nums.begin(), nums.end());    vector> ansList;    findSubsets(0, nums, ds, ansList);    return ansList;} int main() {    int set[] = { 10, 12, 12 };    vector> 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

 // Java program to find all subsets of given set. Any// repeated subset is considered only once in the outputimport java.io.*;import java.util.*; class GFG {    public static void    findSubsets(int ind, int[] nums, ArrayList ds,                ArrayList > 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 >    AllSubsets(int arr[], int n)    {        // your code here        Arrays.sort(arr);        ArrayList > 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));    }}// This code is contributed by Raunak Singh

## Python3

 # Python program to find all subsets of given set. Any# repeated subset is considered only once in the outputdef 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#

 // C# program to find all subsets of given set. Any// repeated subset is considered only once in the outputusing System;using System.Collections.Generic; public class GFG{    static void FindSubsets(int ind, int[] nums, List<int> ds, List> 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> AllSubsets(int[] arr)    {        Array.Sort(arr);        List> ansList = new List>();        FindSubsets(0, arr, new List<int>(), ansList);        return ansList;    }     public static void Main()    {        int[] set = { 10, 12, 12 };        List> 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

 // Javascript program to find all subsets of given set. Any// repeated subset is considered only once in the outputfunction 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:

## Javascript

 

Output

10
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.