Find all distinct subsets of a given set using BitMasking Approach

• Difficulty Level : Hard
• Last Updated : 28 Sep, 2022

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

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:

Python3

 # Python3 program to find all subsets of# given set. Any repeated subset is# considered only once in the output  def printPowerSet(arr, n):     # Function to find all subsets of given set.    # Any repeated subset is considered only    # once in the output    _list = []     # Run counter i from 000..0 to 111..1    for i in range(2**n):        subset = ""         # consider each element in the set        for j in range(n):             # Check if jth bit in the i is set.            # If the bit is set, we consider            # jth element from set            if (i & (1 << j)) != 0:                subset += str(arr[j]) + "|"         # if subset is encountered for the first time        # If we use set, we can directly insert        if subset not in _list and len(subset) > 0:            _list.append(subset)     # consider every subset    for subset in _list:         # split the subset and print its elements        arr = subset.split('|')        for string in arr:            print(string, end=" ")        print()  # Driver Codeif __name__ == '__main__':    arr = [10, 12, 12]    n = len(arr)    printPowerSet(arr, n) # This code is contributed by vibhu4agarwal

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.