Given an array arr[] of distinct positive integers, find all possible subsets of the array, including the empty subset and the subset containing all elements.
Note: The subsets can be returned in any order.
Input: arr[] = [1, 2, 3]
Output: [[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]]
Explanation: The array [1, 2, 3] has 8 subsets: [], [1], [2], [3], [1, 2], [1, 3], [2, 3] and [1, 2, 3].Input: arr[] = [2, 4]
Output: [[], [2], [2, 4], [4]]
Explanation: The array [2, 4] has 4 subsets: [], [2], [4] and [2, 4].
Table of Content
Using Recursion - O(n * 2^n) Time and O(n) Space
The idea is to explore possible choices one by one recursively. For each element, there two options, either include it into subset or exclude it.
For an array of size (n), each element has two choices. Therefore, the total number of possible subsets is (2^n).
Consider the array [1, 2, 3].
The recursion explores both choices for each element until all elements have been processed, generating all 8 subsets.

#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);
cout << "[";
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 << "]";
if (i != res.size() - 1)
cout << ", ";
}
cout << "]" << endl;
return 0;
}
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);
System.out.print("[");
for (int i = 0; i < res.size(); i++) {
System.out.print("[");
for (int j = 0; j < res.get(i).size(); j++) {
System.out.print(res.get(i).get(j));
if (j != res.get(i).size() - 1)
System.out.print(", ");
}
System.out.print("]");
if (i != res.size() - 1)
System.out.print(", ");
}
System.out.println("]");
}
}
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)
print("[", end="")
for i in range(len(res)):
print("[", end="")
for j in range(len(res[i])):
print(res[i][j], end="")
if j != len(res[i]) - 1:
print(", ", end="")
print("]", end="")
if i != len(res) - 1:
print(", ", end="")
print("]")
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);
Console.Write("[");
for (int i = 0; i < res.Count; i++) {
Console.Write("[");
for (int j = 0; j < res[i].Count; j++) {
Console.Write(res[i][j]);
if (j != res[i].Count - 1)
Console.Write(", ");
}
Console.Write("]");
if (i != res.Count - 1)
Console.Write(", ");
}
Console.WriteLine("]");
}
}
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);
process.stdout.write("[");
for (let i = 0; i < res.length; i++) {
process.stdout.write("[");
for (let j = 0; j < res[i].length; j++) {
process.stdout.write(String(res[i][j]));
if (j !== res[i].length - 1)
process.stdout.write(", ");
}
process.stdout.write("]");
if (i !== res.length - 1)
process.stdout.write(", ");
}
console.log("]");
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.
Bit Manipulation - O(n * 2^n) Time and O(n) Space
The idea is to use binary numbers to generate all possible subsets. Each element has two choices: include it in the subset (1) or exclude it (0).
- For an array of size n, there are 2^n possible subsets because each element has two choices.
- Run a loop from 0 to (1 << n) - 1, where 1 << n equals 2^n. Each number represents a unique subset.
- For each number, check every bit using i & (1 << j). If the result is non-zero, include arr[j] in the current subset. Otherwise, exclude it.
- After checking all elements, add the current subset to the result.
Every bitmask represents a unique combination of included and excluded elements. Therefore, checking all 2^n bitmasks generates every possible subset exactly once, including the empty subset.
Consider arr[]= [1, 2, 3].
Generate all the subsets using bit manipulation as shown in the image below:

#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);
cout << "[";
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 << "]";
if (i != res.size() - 1)
cout << ", ";
}
cout << "]" << endl;
return 0;
}
import java.util.ArrayList;
import java.util.List;
class GFG {
public static ArrayList<ArrayList<Integer> >
subsets(int[] arr)
{
int n = arr.length;
ArrayList<ArrayList<Integer> > res
= new ArrayList<>();
// Loop through all possible subsets
for (int i = 0; i < (1 << n); i++) {
ArrayList<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 };
ArrayList<ArrayList<Integer> > res = subsets(arr);
System.out.print("[");
for (int i = 0; i < res.size(); i++) {
System.out.print("[");
for (int j = 0; j < res.get(i).size(); j++) {
System.out.print(res.get(i).get(j));
if (j != res.get(i).size() - 1)
System.out.print(", ");
}
System.out.print("]");
if (i != res.size() - 1)
System.out.print(", ");
}
System.out.println("]");
}
}
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)
print("[", end="")
for i in range(len(res)):
print("[", end="")
for j in range(len(res[i])):
print(res[i][j], end="")
if j != len(res[i]) - 1:
print(", ", end="")
print("]", end="")
if i != len(res) - 1:
print(", ", end="")
print("]")
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);
Console.Write("[");
for (int i = 0; i < res.Count; i++) {
Console.Write("[");
for (int j = 0; j < res[i].Count; j++) {
Console.Write(res[i][j]);
if (j != res[i].Count - 1)
Console.Write(", ");
}
Console.Write("]");
if (i != res.Count - 1)
Console.Write(", ");
}
Console.WriteLine("]");
}
}
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);
process.stdout.write("[");
for (let i = 0; i < res.length; i++) {
process.stdout.write("[");
for (let j = 0; j < res[i].length; j++) {
process.stdout.write(String(res[i][j]));
if (j !== res[i].length - 1)
process.stdout.write(", ");
}
process.stdout.write("]");
if (i !== res.length - 1)
process.stdout.write(", ");
}
console.log("]");
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.