Given a string, we have to find out all its subsequences of it. A String is said to be a subsequence of another String, if it can be obtained by deleting 0 or more character without changing its order.
For example, sub-sequences of "geeks" are

Examples:
Input : ab
Output : "", "a", "b", "ab"Input : abc
Output : "", "a", "b", "c", "ab", "ac", "bc", "abc"
Table of Content
Pick and Don't Pick Recursion - O(n × 2 ^ n) Time and O(n × 2 ^ n) Space
We begin with the last character and for every character, we make two choices,
- Pick: make a recursive call for next index and current subsequence appended with the current character.
- Do Not Pick: make a recursive call for next index and current subsequence as it is.
#include <bits/stdc++.h>
using namespace std;
void solve(int i, string &s, string curr, vector<string>& ans) {
if (i == s.length()) {
ans.push_back(curr);
return;
}
// Pick the current character
solve(i + 1, s, curr + s[i], ans);
// Don't pick the current character
solve(i + 1, s, curr, ans);
}
vector<string> powerSet(string &s) {
vector<string> ans;
solve(0, s, "", ans);
sort(ans.begin(), ans.end());
return ans;
}
int main() {
string s = "abc";
vector<string> ans = powerSet(s);
for (string str : ans)
cout << str << " ";
return 0;
}
import java.util.ArrayList;
import java.util.Collections;
class GFG {
static void solve(int i, String s, String curr,
ArrayList<String> ans) {
if (i == s.length()) {
ans.add(curr);
return;
}
// Pick the current character
solve(i + 1, s, curr + s.charAt(i), ans);
// Don't pick the current character
solve(i + 1, s, curr, ans);
}
static ArrayList<String> powerSet(String s) {
ArrayList<String> ans = new ArrayList<>();
solve(0, s, "", ans);
Collections.sort(ans);
return ans;
}
public static void main(String[] args) {
String s = "abc";
ArrayList<String> ans = powerSet(s);
for (String str : ans)
System.out.print(str + " ");
}
}
def solve(i, s, curr, ans):
if i == len(s):
ans.append(curr)
return
# Pick the current character
solve(i + 1, s, curr + s[i], ans)
# Don't pick the current character
solve(i + 1, s, curr, ans)
def powerSet(s):
ans = []
solve(0, s, "", ans)
ans.sort()
return ans
if __name__ == "__main__":
s = "abc"
ans = powerSet(s)
for string in ans:
print(string, end=" ")
using System;
using System.Collections.Generic;
class GFG
{
static void solve(int i, string s, string curr,
List<string> ans)
{
if (i == s.Length)
{
ans.Add(curr);
return;
}
// Pick the current character
solve(i + 1, s, curr + s[i], ans);
// Don't pick the current character
solve(i + 1, s, curr, ans);
}
static List<string> powerSet(string s)
{
List<string> ans = new List<string>();
solve(0, s, "", ans);
ans.Sort();
return ans;
}
static void Main()
{
string s = "abc";
List<string> ans = powerSet(s);
foreach (string str in ans)
Console.Write(str + " ");
}
}
function solve(i, s, curr, ans) {
if (i === s.length) {
ans.push(curr);
return;
}
// Pick the current character
solve(i + 1, s, curr + s[i], ans);
// Don't pick the current character
solve(i + 1, s, curr, ans);
}
function powerSet(s) {
let ans = [];
solve(0, s, "", ans);
ans.sort();
return ans;
}
// Driver code
let s = "abc";
let ans = powerSet(s);
for (let str of ans) {
console.log(str);
}
Output
a ab abc ac b bc c
Further Optimization : Instead of generating a substring every-time, we can pass index as additional parameter and pass reference of the same string.
Incremental - O(n × 2 ^ n) Time and O(n × 2 ^ n) Space
Start with an empty subsequence.
For each character,
- Create new subsequences by adding the current character to every existing subsequence,
- Then add these new subsequences to the result.
#include <bits/stdc++.h>
using namespace std;
vector<string> powerSet(string &s) {
vector<string> ans = {""};
for (char ch : s) {
int size = ans.size();
// Add current character to existing subsequences
for (int i = 0; i < size; i++) {
ans.push_back(ans[i] + ch);
}
}
sort(ans.begin(), ans.end());
return ans;
}
int main() {
string s = "abc";
vector<string> ans = powerSet(s);
for (string str : ans)
cout << str << " ";
return 0;
}
import java.util.ArrayList;
import java.util.Collections;
class GFG {
static ArrayList<String> powerSet(String s) {
ArrayList<String> ans = new ArrayList<>();
ans.add("");
for (char ch : s.toCharArray()) {
int size = ans.size();
// Add current character to existing subsequences
for (int i = 0; i < size; i++) {
ans.add(ans.get(i) + ch);
}
}
Collections.sort(ans);
return ans;
}
public static void main(String[] args) {
String s = "abc";
ArrayList<String> ans = powerSet(s);
for (String str : ans)
System.out.print(str + " ");
}
}
def powerSet(s):
ans = [""]
for ch in s:
size = len(ans)
# Add current character to existing subsequences
for i in range(size):
ans.append(ans[i] + ch)
ans.sort()
return ans
if __name__ == "__main__":
s = "abc"
ans = powerSet(s)
for string in ans:
print(string, end=" ")
using System;
using System.Collections.Generic;
class GFG
{
static List<string> powerSet(string s)
{
List<string> ans = new List<string>();
ans.Add("");
foreach (char ch in s)
{
int size = ans.Count;
// Add current character to existing subsequences
for (int i = 0; i < size; i++)
{
ans.Add(ans[i] + ch);
}
}
ans.Sort();
return ans;
}
static void Main()
{
string s = "abc";
List<string> ans = powerSet(s);
foreach (string str in ans)
Console.Write(str + " ");
}
}
function powerSet(s) {
let ans = [""];
for (let ch of s) {
let size = ans.length;
// Add current character to existing subsequences
for (let i = 0; i < size; i++) {
ans.push(ans[i] + ch);
}
}
ans.sort();
return ans;
}
// Driver code
let s = "abc";
let ans = powerSet(s);
for (let str of ans) {
console.log(str);
}
Output
a ab abc ac b bc c
Binary Representation - O(n × 2 ^ n) Time and O(n × 2 ^ n) Space
There are 2ⁿ possible subsequences, so consider every number from 0 to 2ⁿ - 1.
- Treat each number as a bitmask
- A set bit means the corresponding character is included in the subsequence and an unset bit means it is skipped.
For a string of length n, there are exactly 2ⁿ subsequences.
- Generate numbers from
0to2ⁿ - 1. - Consider each number as a binary representation.
- Each bit corresponds to one character.
- Bit = 1 → include the character.
- Bit = 0 → skip the character.
For "abc":
- 000 → ""
- 001 → "c"
- 010 → "b"
- 011 → "bc"
- 100 → "a"
- 101 → "ac"
- 110 → "ab"
- 111 → "abc"
Thus, every possible combination of characters is generated
#include <bits/stdc++.h>
using namespace std;
vector<string> powerSet(string &s) {
int n = s.length();
vector<string> ans;
// Generate all possible bitmasks
for (int mask = 0; mask < (1 << n); mask++) {
string curr = "";
// Check each bit
for (int j = 0; j < n; j++) {
if (mask & (1 << j))
curr += s[j];
}
ans.push_back(curr);
}
sort(ans.begin(), ans.end());
return ans;
}
int main() {
string s = "abc";
vector<string> ans = powerSet(s);
for (string str : ans)
cout << str << " ";
return 0;
}
import java.util.ArrayList;
import java.util.Collections;
class GFG {
static ArrayList<String> powerSet(String s) {
int n = s.length();
ArrayList<String> ans = new ArrayList<>();
// Generate all possible bitmasks
for (int mask = 0; mask < (1 << n); mask++) {
String curr = "";
// Check each bit
for (int j = 0; j < n; j++) {
if ((mask & (1 << j)) != 0)
curr += s.charAt(j);
}
ans.add(curr);
}
Collections.sort(ans);
return ans;
}
public static void main(String[] args) {
String s = "abc";
ArrayList<String> ans = powerSet(s);
for (String str : ans)
System.out.print(str + " ");
}
}
def powerSet(s):
n = len(s)
ans = []
# Generate all possible bitmasks
for mask in range(1 << n):
curr = ""
# Check each bit
for j in range(n):
if mask & (1 << j):
curr += s[j]
ans.append(curr)
ans.sort()
return ans
if __name__ == "__main__":
s = "abc"
ans = powerSet(s)
for string in ans:
print(string, end=" ")
using System;
using System.Collections.Generic;
class GFG
{
static List<string> powerSet(string s)
{
int n = s.Length;
List<string> ans = new List<string>();
// Generate all possible bitmasks
for (int mask = 0; mask < (1 << n); mask++)
{
string curr = "";
// Check each bit
for (int j = 0; j < n; j++)
{
if ((mask & (1 << j)) != 0)
curr += s[j];
}
ans.Add(curr);
}
ans.Sort();
return ans;
}
static void Main()
{
string s = "abc";
List<string> ans = powerSet(s);
foreach (string str in ans)
Console.Write(str + " ");
}
}
function powerSet(s) {
let n = s.length;
let ans = [];
// Generate all possible bitmasks
for (let mask = 0; mask < (1 << n); mask++) {
let curr = "";
// Check each bit
for (let j = 0; j < n; j++) {
if (mask & (1 << j)) {
curr += s[j];
}
}
ans.push(curr);
}
ans.sort();
return ans;
}
// Driver code
let s = "abc";
let ans = powerSet(s);
for (let str of ans) {
console.log(str);
}
Output
a ab abc ac b bc c