Subset generation using bits (also called bitmasking) is a common and efficient technique to generate all possible subsets (also called the power set) of a given array or list.
Concept:
If an array has n elements, there are 2^n possible subsets. Each subset can be represented by a binary number of n bits:
- Each bit in the binary number tells whether to include (1) or exclude (0) the corresponding element.
Example:
Given the array:
arr = [1, 2, 3]
There are 2^3 = 8 subsets. We loop from 0 to 7 (inclusive), and for each number, check which bits are set to decide which elements to include.
Code (Python):
def generate_subsets(arr):
n = len(arr)
subsets = []
for i in range(1 << n): # from 0 to 2^n - 1
subset = []
for j in range(n):
if i & (1 << j): # check if j-th bit in i is set
subset.append(arr[j])
subsets.append(subset)
return subsets
# Example
arr = [1, 2, 3]
all_subsets = generate_subsets(arr)
for subset in all_subsets:
print(subset)Code (CPP):
#include <iostream>
#include <vector>
using namespace std;
void generateSubsets(vector<int>& arr) {
int n = arr.size();
int totalSubsets = 1 << n; // 2^n subsets
for (int mask = 0; mask < totalSubsets; ++mask) {
vector<int> subset;
for (int j = 0; j < n; ++j) {
if (mask & (1 << j)) {
subset.push_back(arr[j]);
}
}
// Print the subset
cout << "{ ";
for (int val : subset) {
cout << val << " ";
}
cout << "}" << endl;
}
}
int main() {
vector<int> arr = {1, 2, 3};
generateSubsets(arr);
return 0;
}Output:
[]
[1]
[2]
[1, 2]
[3]
[1, 3]
[2, 3]
[1, 2, 3]
Time Complexity:
- O(n * 2^n) — for each of the 2^n subsets, we loop through up to n elements.