Open In App

Print all subsets of a given Set or Array

Last Updated : 22 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array arr of size n, your task is to print all the subsets of the array  in lexicographical order.

A subset is any selection of elements from an array, where the order does not matter, and no element appears more than once. It can include any number of elements, from none (the empty subset) to all the elements of the array.

Examples:

Input: arr[] = [1, 2, 3]
Output: [[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]]
Explanation: The subsets of [1, 2, 3] in lexicographical order are:
[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]

Input: arr[] = [2, 4]
Output: [[], [2], [2, 4], [4]]
Explanation: The subsets of [1, 2] in lexicographical order are:
[], [1], [1, 2], [2]

How many Subsets are possible for an array of size n?

Before jumping into the solution, can we observe some kind of relation between the size of array n and the number of subsets formed by that array? The answer is YES, there exists a relation that is given by the following formula:

Number of Subsets of an array of size n = 2n

Proof: For each element of the array we have 2 choices:

  • Choice 1: Include it into the subset.
  • Choice 2: Exclude it from the subset.

Since, each element has 2 choice to contribute into the subset and we have total n elements, therefore total subsets = 2n

Let's see how can we construct our solution from this observation.

[Expected Approach] Using Backtracking - O(2^n*n^2) Time and O(n) Space

The idea is to use backtracking to explore all possible choices one by one recursively. For each element, there two options, either include it into subset or exclude it.

State Space Tree for printing all subsets using Backtracking:

Suppose an array of size 3 having elements [1, 2, 3], the state space tree can be constructed as below:

State Space Tree of Subset

Follow the the steps below to implement the above idea:

  • Initialize an empty list subset to store the current subset elements, and a 2D list res to store all subsets.
  • Recursively iterate through the array elements.
    • Include (add) the current element to subset and recursively call the function for the next index.
    • Exclude (remove) the current element from subset to backtrack, and recursively call the function for the next index.
C++
// C++ program to print all subsets
// of a given Set or Array
#include <iostream>
#include <vector>
#include <algorithm> 
using namespace std;

void subsetRecur(int i, vector<int>& arr, 
       vector<vector<int>>& res, vector<int>& subset) {
    
    // add subset at end of array
    if (i == arr.size()) {
        res.push_back(subset);
        return;
    }
    
    // include the current value and 
    // recursively find all subsets
    subset.push_back(arr[i]);
    subsetRecur(i+1, arr, res, subset);
    
    // exclude the current value and 
    // recursively find all subsets.
    subset.pop_back();
    subsetRecur(i+1, arr, res, subset);
}

vector<vector<int> > subsets(vector<int>& arr) {
    
    sort(arr.begin(),arr.end());
    vector<int> subset;
    vector<vector<int>> res;
    subsetRecur(0, arr, res, subset);
    sort(res.begin(), res.end());
    return res;
}

int main() {
    vector<int> arr = { 1, 2, 3 };
    vector<vector<int> > res = subsets(arr);
    
    for (int i = 0; i < res.size(); i++) {
        for (int j = 0; j < res[i].size(); j++)
            cout << res[i][j] << " ";
        cout << endl;
    }

    return 0;
}
Java
import java.util.*;

class GfG {

    static void subsetRecur(int i, int[] arr,
                            ArrayList<ArrayList<Integer>> res,
                            ArrayList<Integer> subset) {
        if (i == arr.length) {
            res.add(new ArrayList<>(subset));
            return;
        }

        // Include the current element
        subset.add(arr[i]);
        subsetRecur(i + 1, arr, res, subset);

        // Exclude the current element
        subset.remove(subset.size() - 1);
        subsetRecur(i + 1, arr, res, subset);
    }

    static ArrayList<ArrayList<Integer>> subsets(int[] arr) {
        Arrays.sort(arr); // Sort array once

        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        ArrayList<Integer> subset = new ArrayList<>();
        subsetRecur(0, arr, res, subset);

        // Lexicographically sort all subsets
        res.sort((a, b) -> {
            int minLength = Math.min(a.size(), b.size());
            for (int i = 0; i < minLength; i++) {
                int cmp = Integer.compare(a.get(i), b.get(i));
                if (cmp != 0)
                    return cmp;
            }
            return Integer.compare(a.size(), b.size());
        });

        return res;
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        ArrayList<ArrayList<Integer>> res = subsets(arr);

        for (ArrayList<Integer> subset : res) {
            for (int num : subset) {
                System.out.print(num + " ");
            }
            System.out.println();
        }
    }
}
Python
# Python program to print all subsets
# of a given Set or Array

def subsetRecur(i, arr, res, subset):
    
    # add subset at end of array
    if i == len(arr):
        res.append(list(subset))
        return
    
    # include the current value and 
    # recursively find all subsets
    subset.append(arr[i])
    subsetRecur(i + 1, arr, res, subset)
    
    # exclude the current value and 
    # recursively find all subsets
    subset.pop()
    subsetRecur(i + 1, arr, res, subset)

def subsets(arr):
    subset = []
    arr.sort()
    res = []
    subsetRecur(0, arr, res, subset)
    res.sort()
    return res

if __name__ == "__main__":
    arr = [1, 2, 3]
    res = subsets(arr)
    
    for subset in res:
        for num in subset:
            print(num, end=" ")
        print()
C#
using System;
using System.Collections.Generic;

class GfG {
    static void subsetRecur(int i, int[] arr, 
                            List<List<int>> res, 
                            List<int> subset) {

        if (i == arr.Length) {
            res.Add(new List<int>(subset));
            return;
        }

        // Include the current value
        subset.Add(arr[i]);
        subsetRecur(i + 1, arr, res, subset);

        // Exclude the current value
        subset.RemoveAt(subset.Count - 1);
        subsetRecur(i + 1, arr, res, subset);
    }

    static List<List<int>> subsets(int[] arr) {
        Array.Sort(arr);

        List<int> subset = new List<int>();
        List<List<int>> res = new List<List<int>>();
        subsetRecur(0, arr, res, subset);

        res.Sort((a, b) =>
        {
            int len = Math.Min(a.Count, b.Count);
            for (int i = 0; i < len; i++) {
                int cmp = a[i].CompareTo(b[i]);
                if (cmp != 0)
                    return cmp;
            }
            return a.Count.CompareTo(b.Count);
        });

        return res;
    }

    static void Main(string[] args) {
        int[] arr = { 1, 2, 3 };
        List<List<int>> res = subsets(arr);

        foreach (var subset in res) {
            foreach (var num in subset) {
                Console.Write(num + " ");
            }
            Console.WriteLine();
        }
    }
}
JavaScript
function subsetRecur(i, arr, res, subset) {
    
    // add subset at end of array
    if (i === arr.length) {
        res.push([...subset]);
        return;
    }
    
    // include the current value and 
    // recursively find all subsets
    subset.push(arr[i]);
    subsetRecur(i + 1, arr, res, subset);
    
    // exclude the current value and 
    // recursively find all subsets
    subset.pop();
    subsetRecur(i + 1, arr, res, subset);
}

function subsets(arr) {
    
    arr.sort((a, b) => a - b);
    const subset = [];
    const res = [];
    subsetRecur(0, arr, res, subset);
    
    // Lexicographical sort of subsets
    res.sort((a, b) => {
        const minLen = Math.min(a.length, b.length);
        for (let i = 0; i < minLen; i++) {
            if (a[i] !== b[i]) return a[i] - b[i];
        }
        return a.length - b.length;
    });

    return res;
}

const arr = [1, 2, 3];
const res = subsets(arr);

for (const subset of res) {
    console.log(subset.join(" "));
}

Output
1 
1 2 
1 2 3 
1 3 
2 
2 3 
3 

Time Complexity: O(2n*n2), where n is the size of given array.
Auxiliary Space:  O(2n) if we consider the output array. O(n) otherwise.

[Alternate Approach] Using Bit Manipulation - O(2^n*n^2) Time and O(1) Space

This approach is simpler compared to backtracking, as it just requires basic knowledge of bits.

Observation: A bit can be either 0 or 1. What can we deduce from this?

Since, each element has only two choices i.e. either get included or get excluded. Assign these choices to a bit representation such that:
0 means Excluded
1 means Included
i'th bit represents i'th element of the array

Now let's say, there are n elements in the array. This array will have 2n subsets. These subsets can be uniquely expressed in form of Bit representation of number from 0 to (2n)-1.

Example: If elements in an array of size 2 = {A, B}
All the subsets of this array form the bit representation of number from 0 to (22)-1 i.e. 0 to 3

0 = 00 => A excluded, B excluded => { empty }
1 = 01 => A excluded, B included => { B }
2 = 10 => A included, B excluded => { A }
3 = 11 => A included, B included=> { A, B }

Illustration:

Suppose given an array of size 3 = {1, 2, 3}. Generate all the subsets using bit manipulation as shown in the image below:

bit-representation-of-subset

Below are the step-by-step approach:

  • Iterate numbers from 0 to (2n)-1
  • Generate binary representation of that number and include the elements of array as per below cases:
    • If the i'th bit is 1, then include i'th element of the array into current subset
    • If the i'th bit is 0, do nothing and continue.
  • Each bit representation of the number will give a unique subset.
C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// Function to find the subsets of the given array
vector<vector<int>> subsets(vector<int> &arr) {
    int n = arr.size();
    vector<vector<int>> res;
    sort(arr.begin(), arr.end());
    // Loop through all possible 
    // subsets using bit manipulation
    for (int i = 0; i < (1 << n); i++) {
        vector<int> subset;

        // Loop through all elements 
        // of the input array
        for (int j = 0; j < n; j++) {

            // Check if the jth bit is 
            // set in the current subset
            if ((i & (1 << j)) != 0) {

                // If the jth bit is set, add 
                // the jth element to the subset
                subset.push_back(arr[j]);
            }
        }
        
        // Push the subset into result
        res.push_back(subset);
    }
    
    sort(res.begin(), res.end());
    return res;
}

int main() {
    vector<int> arr = { 1, 2, 3 };
    vector<vector<int> > res = subsets(arr);
    
    for (int i = 0; i < res.size(); i++) {
        for (int j = 0; j < res[i].size(); j++)
            cout << res[i][j] << " ";
        cout << endl;
    }

    return 0;
}
Java
import java.util.*;

class GfG {

    // Function to find the subsets of the given array
    static ArrayList<ArrayList<Integer>> subsets(int[] arr) {
        Arrays.sort(arr); 
        
        int n = arr.length;
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();

        // Loop through all possible subsets using bitmasking
        for (int i = 0; i < (1 << n); i++) {
            ArrayList<Integer> subset = new ArrayList<>();

            for (int j = 0; j < n; j++) {
                // Check if j-th bit is set in i
                if ((i & (1 << j)) != 0) {
                    subset.add(arr[j]);
                }
            }

            res.add(subset);
        }

        // Lexicographically sort of subsets
        res.sort((a, b) -> {
            int len = Math.min(a.size(), b.size());
            for (int i = 0; i < len; i++) {
                int cmp = Integer.compare(a.get(i), b.get(i));
                if (cmp != 0) return cmp;
            }
            return Integer.compare(a.size(), b.size());
        });

        return res;
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        ArrayList<ArrayList<Integer>> res = subsets(arr);

        for (ArrayList<Integer> subset : res) {
            for (int num : subset) {
                System.out.print(num + " ");
            }
            System.out.println();
        }
    }
}
Python
# Python program to print all subsets
# of a given Set or Array

# Function to find the subsets of the given array
def subsets(arr):
    n = len(arr)
    arr.sort()
    res = []
    
    # Loop through all possible 
    # subsets using bit manipulation
    for i in range(1 << n):
        subset = []

        # Loop through all elements 
        # of the input array
        for j in range(n):

            # Check if the jth bit is 
            # set in the current subset
            if (i & (1 << j)) != 0:

                # If the jth bit is set, add 
                # the jth element to the subset
                subset.append(arr[j])
        
    
        # Push the subset into result
        res.append(subset)
    
    res.sort()
    return res

if __name__ == "__main__":
    arr = [1, 2, 3]
    res = subsets(arr)
    
    for subset in res:
        print(" ".join(map(str, subset)))
C#
using System;
using System.Collections.Generic;
using System.Linq;

class GfG {
  
    // Function to find the subsets of the given array
    static List<List<int>> subsets(int[] arr) {
        // Sort the array first
        Array.Sort(arr);

        int n = arr.Length;
        List<List<int>> res = new List<List<int>>();
        
        // Loop through all possible subsets using bit manipulation
        for (int i = 0; i < (1 << n); i++) {
            List<int> subset = new List<int>();

            for (int j = 0; j < n; j++) {
                if ((i & (1 << j)) != 0) {
                    subset.Add(arr[j]);
                }
            }

            res.Add(subset);
        }

        // Sort the list of subsets
        res.Sort((a, b) => {
            int minLength = Math.Min(a.Count, b.Count);
            for (int i = 0; i < minLength; i++) {
                if (a[i] != b[i]) return a[i].CompareTo(b[i]);
            }
            return a.Count.CompareTo(b.Count);
        });

        return res;
    }

    static void Main(string[] args) {
        // Unsorted input for testing
        int[] arr = {1, 2, 3}; 
        List<List<int>> res = subsets(arr);
        
        foreach (var subset in res) {
            Console.WriteLine(string.Join(" ", subset));
        }
    }
}
JavaScript
// Function to find the subsets of the given array
function subsets(arr) {
    // Sort the input array first
    arr.sort((a, b) => a - b);

    const n = arr.length;
    const res = [];

    // Generate all subsets using bit manipulation
    for (let i = 0; i < (1 << n); i++) {
        const subset = [];

        for (let j = 0; j < n; j++) {
            if ((i & (1 << j)) !== 0) {
                subset.push(arr[j]);
            }
        }

        res.push(subset);
    }

    // Sort the list of subsets lexicographically
    res.sort((a, b) => {
        const len = Math.min(a.length, b.length);
        for (let i = 0; i < len; i++) {
            if (a[i] !== b[i]) {
                return a[i] - b[i];
            }
        }
        return a.length - b.length;
    });

    return res;
}

// Test
const arr = [3, 1, 2];  // Unsorted input for testing
const res = subsets(arr);

for (const subset of res) {
    console.log(subset.join(" "));
}

Output
1 
1 2 
1 2 3 
1 3 
2 
2 3 
3 

Time Complexity: O(2n*n2), where n is the size of given array.
Auxiliary Space:  O(2n) if we consider the output array. O(1) otherwise.


Next Article
Article Tags :

Similar Reads