All Subsets of a given Array
Last Updated :
29 Sep, 2025
Given an integer array arr[], Find all the subsets of the array.
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] 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 [2, 4] are: [[], [2], [2, 4], [4]]
How many Subsets are possible for an array of size n?
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
[Approach - 1] Using Backtracking
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:
C++
#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) {
vector<int> subset;
vector<vector<int>> res;
// finding recursively
subsetRecur(0, arr, res, subset);
return res;
}
int main() {
vector<int> arr = { 1, 2, 3 };
vector<vector<int> > res = subsets(arr);
for (int i = 0; i < res.size(); i++) {
cout << "[";
for (int j = 0; j < res[i].size(); j++) {
cout << res[i][j];
if (j != res[i].size() - 1) cout << ", ";
}
cout << "]" << endl;
}
return 0;
}
Java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
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) {
ArrayList<ArrayList<Integer>> res = new ArrayList<>();
ArrayList<Integer> subset = new ArrayList<>();
// finding recursively
subsetRecur(0, arr, res, subset);
return res;
}
public static void main(String[] args) {
int[] arr = {1, 2, 3};
ArrayList<ArrayList<Integer>> res = subsets(arr);
for (ArrayList<Integer> subset : res) {
System.out.print("[");
for (int i = 0; i < subset.size(); i++) {
System.out.print(subset.get(i));
if (i != subset.size() - 1) System.out.print(", ");
}
System.out.println("]");
}
}
}
Python
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 = []
res = []
# finding recursively
subsetRecur(0, arr, res, subset)
return res
if __name__ == "__main__":
arr = [1, 2, 3]
res = subsets(arr)
for subset in res:
print("[", end="")
print(", ".join(str(num) for num in subset), 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) {
List<int> subset = new List<int>();
List<List<int>> res = new List<List<int>>();
// finding recursively
subsetRecur(0, arr, res, subset);
return res;
}
static void Main(string[] args) {
int[] arr = { 1, 2, 3 };
List<List<int>> res = subsets(arr);
foreach (var subset in res) {
Console.Write("[");
Console.Write(string.Join(", ", subset));
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) {
const subset = [];
const res = [];
// finding recursively
subsetRecur(0, arr, res, subset);
return res;
}
//Driver code
const arr = [1, 2, 3];
const res = subsets(arr);
for (const subset of res) {
console.log("[" + subset.join(", ") + "]");
}
Output[1, 2, 3]
[1, 2]
[1, 3]
[1]
[2, 3]
[2]
[3]
[]
Time Complexity: O(n * 2n), generating all subsets requires 2n recursive calls, and copying each subset of size up to n takes O(n) time.
Auxiliary Space: O(n), recursion stack and temporary subset use at most n space at a time.
[Approach - 2] Using Bit Manipulation
This approach is simpler compared to backtracking, as it just requires basic knowledge of bits.
Each element in an array has only two choices: it can either be included or excluded from a subset. We can represent these choices using bits: 0 means excluded, and 1 means included. The i-th bit corresponds to the i-th element of the array.
For an array of size n, there are 2n possible subsets, and each subset can be uniquely represented by the bit representation of numbers from 0 to 2n - 1.
Example: Consider an array [A, B]:
0 → 00 → A excluded, B excluded → []
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:
C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<vector<int>> subsets(vector<int> &arr) {
int n = arr.size();
vector<vector<int>> res;
// Loop through all possible subsets
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
if ((i & (1 << j)) != 0) {
subset.push_back(arr[j]);
}
}
// Push the subset into result
res.push_back(subset);
}
return res;
}
int main() {
vector<int> arr = { 1, 2, 3 };
vector<vector<int> > res = subsets(arr);
for (int i = 0; i < res.size(); i++) {
cout << "[";
for (int j = 0; j < res[i].size(); j++) {
cout << res[i][j];
if (j != res[i].size() - 1) cout << ", ";
}
cout << "]" << endl;
}
return 0;
}
Java
import java.util.ArrayList;
import java.util.List;
class GFG {
public static List<List<Integer>> subsets(int[] arr) {
int n = arr.length;
List<List<Integer>> res = new ArrayList<>();
// Loop through all possible subsets
for (int i = 0; i < (1 << n); i++) {
List<Integer> subset = new ArrayList<>();
// Loop through all elements of the input array
for (int j = 0; j < n; j++) {
// Check if the jth bit is set
if ((i & (1 << j)) != 0) {
subset.add(arr[j]);
}
}
// Add subset to result
res.add(subset);
}
return res;
}
public static void main(String[] args) {
int[] arr = {1, 2, 3};
List<List<Integer>> res = subsets(arr);
for (int i = 0; i < res.size(); i++) {
List<Integer> subset = res.get(i);
System.out.print("[");
for (int j = 0; j < subset.size(); j++) {
System.out.print(subset.get(j));
if (j != subset.size() - 1)
System.out.print(", ");
}
System.out.println("]");
}
}
}
Python
def subsets(arr):
n = len(arr)
res = []
# Loop through all possible subsets
for i in range(1 << n):
subset = []
# Loop through all elements
for j in range(n):
# Check if jth bit is set
if i & (1 << j):
subset.append(arr[j])
# Add subset to result
res.append(subset)
return res
if __name__ == '__main__':
arr = [1, 2, 3]
res = subsets(arr)
for subset in res:
print("[", end="")
print(", ".join(map(str, subset)), end="")
print("]")
C#
using System;
using System.Collections.Generic;
class GFG {
public static List<List<int>> Subsets(int[] arr) {
int n = arr.Length;
var res = new List<List<int>>();
// Loop through all possible subsets
for (int i = 0; i < (1 << n); i++) {
var subset = new List<int>();
// Loop through all elements
for (int j = 0; j < n; j++) {
// Check if jth bit is set
if ((i & (1 << j)) != 0) {
subset.Add(arr[j]);
}
}
// Add subset to result
res.Add(subset);
}
return res;
}
static void Main() {
int[] arr = {1, 2, 3};
var res = Subsets(arr);
foreach (var subset in res) {
Console.Write("[");
Console.Write(string.Join(", ", subset));
Console.WriteLine("]");
}
}
}
JavaScript
function subsets(arr) {
const n = arr.length;
const res = [];
// Loop through all possible subsets
for (let i = 0; i < (1 << n); i++) {
const subset = [];
// Loop through all elements
for (let j = 0; j < n; j++) {
// Check if jth bit is set
if ((i & (1 << j)) !== 0) {
subset.push(arr[j]);
}
}
// Add subset to result
res.push(subset);
}
return res;
}
// Driver code
const arr = [1, 2, 3];
const res = subsets(arr);
res.forEach(subset => {
console.log("[" + subset.join(", ") + "]");
});
Output[]
[1]
[2]
[1, 2]
[3]
[1, 3]
[2, 3]
[1, 2, 3]
Time Complexity: O(n * 2n), generating all subsets requires 2n recursive calls, and copying each subset of size up to n takes O(n) time.
Auxiliary Space: O(n), temporary subset at most n space at a time.
Explore
DSA Fundamentals
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem