Print all Subsequences of String which Start with Vowel and End with Consonant. (original) (raw)
Last Updated : 10 Jun, 2026
Given a string **s, find all unique subsequences of **s which start with a vowel and end with a consonant.
- The result must be returned in lexicographically sorted order.
- If there are no valid subsequences, return an empty list.
**Examples:
**Input: s = "abc"
**Output: ["ab", "abc", "ac"]
**Explanation: "ab", "abc" and "ac" are all possible unique subsequences which start with a vowel and end with a consonant.**Input: s = "rtmkstdh"
**Output: [ ]
**Explanation: There are no valid subsequences since the string contains no vowels.
Table of Content
- [Naive Approach] Using Recursion and Backtracking - O(n * 2^n) Time and O(n * 2^n) Space
- [Expected Approach] Using Bit Masking - O(n * 2^n) Time and O(n * 2^n) Space
[Naive Approach] Using Recursion and Backtracking - O(n * 2^n) Time and O(n * 2^n) Space
The idea is to generate all possible subsequences of the string using recursion. At each index we make two choices - include the current character or exclude it. Once we reach the end of the string, we check if the generated subsequence starts with a vowel and ends with a consonant. We use an ordered set to automatically handle duplicates and maintain lexicographic order. Finally we convert the set to a list and return it.
C++ `
#include #include #include #include using namespace std;
bool isVowel(char ch) { return ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u'; }
void findSubsequences(int index, int n, string &s, string ¤t, set &st) {
// If we have reached the end of string check if valid subsequence
if (index == n)
{
// Add if non empty starts with vowel and ends with consonant
if (!current.empty() && isVowel(current[0]) && !isVowel(current.back()))
st.insert(current);
return;
}
// Include current character and recurse
current.push_back(s[index]);
findSubsequences(index + 1, n, s, current, st);
// Exclude current character and recurse
current.pop_back();
findSubsequences(index + 1, n, s, current, st);}
vector findSubseq(string s) {
int n = s.length();
string current = "";
set<string> st;
// Find all valid subsequences using recursion
findSubsequences(0, n, s, current, st);
// Convert set to vector for return
return vector<string>(st.begin(), st.end());}
int main() { string s = "abc"; vector result = findSubseq(s); for (int i = 0; i < result.size(); i++) { if (i != 0) cout << " "; cout << result[i]; } cout << endl; return 0; }
Java
import java.util.ArrayList; import java.util.TreeSet;
class GFG {
static boolean isVowel(char ch) {
return ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u';
}
static void findSubsequences(int index, int n, String s, StringBuilder current, TreeSet<String> st) {
// If we have reached the end of string check if valid subsequence
if (index == n) {
// Add if non empty starts with vowel and ends with consonant
String curr = current.toString();
if (!curr.isEmpty() && isVowel(curr.charAt(0)) && !isVowel(curr.charAt(curr.length() - 1)))
st.add(curr);
return;
}
// Include current character and recurse
current.append(s.charAt(index));
findSubsequences(index + 1, n, s, current, st);
// Exclude current character and recurse
current.deleteCharAt(current.length() - 1);
findSubsequences(index + 1, n, s, current, st);
}
static ArrayList<String> findSubseq(String s) {
int n = s.length();
StringBuilder current = new StringBuilder();
TreeSet<String> st = new TreeSet<>();
// Find all valid subsequences using recursion
findSubsequences(0, n, s, current, st);
// Convert TreeSet to ArrayList for return
return new ArrayList<>(st);
}
public static void main(String[] args) {
String s = "abc";
ArrayList<String> result = findSubseq(s);
System.out.println(String.join(" ", result));
}}
Python
def isVowel(ch): return ch in 'aeiou'
def findSubsequences(index, n, s, current, st):
# If we have reached the end of string check if valid subsequence
if index == n:
# Add if non empty starts with vowel and ends with consonant
if current and isVowel(current[0]) and not isVowel(current[-1]):
st.add(current)
return
# Include current character and recurse
findSubsequences(index + 1, n, s, current + s[index], st)
# Exclude current character and recurse
findSubsequences(index + 1, n, s, current, st)def findSubseq(s):
n = len(s)
st = set()
# Find all valid subsequences using recursion
findSubsequences(0, n, s, "", st)
# Convert set to sorted list for return
return sorted(st)if name == "main": s = "abc" result = findSubseq(s) print(' '.join(result))
C#
using System; using System.Collections.Generic;
class GFG {
static bool isVowel(char ch) {
return ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u';
}
static void findSubsequences(int index, int n, string s, string current, SortedSet<string> st) {
// If we have reached the end of string check if valid subsequence
if (index == n) {
// Add if non empty starts with vowel and ends with consonant
if (current.Length > 0 && isVowel(current[0]) && !isVowel(current[current.Length - 1]))
st.Add(current);
return;
}
// Include current character and recurse
findSubsequences(index + 1, n, s, current + s[index], st);
// Exclude current character and recurse
findSubsequences(index + 1, n, s, current, st);
}
static List<string> findSubseq(string s) {
int n = s.Length;
SortedSet<string> st = new SortedSet<string>();
// Find all valid subsequences using recursion
findSubsequences(0, n, s, "", st);
// Convert SortedSet to List for return
return new List<string>(st);
}
static void Main() {
string s = "abc";
List<string> result = findSubseq(s);
Console.WriteLine(string.Join(" ", result));
}}
JavaScript
function isVowel(ch) { return 'aeiou'.includes(ch); }
function findSubsequences(index, n, s, current, st) {
// If we have reached the end of string check if valid subsequence
if (index === n) {
// Add if non empty starts with vowel and ends with consonant
if (current.length > 0 && isVowel(current[0]) && !isVowel(current[current.length - 1]))
st.add(current);
return;
}
// Include current character and recurse
findSubsequences(index + 1, n, s, current + s[index], st);
// Exclude current character and recurse
findSubsequences(index + 1, n, s, current, st);}
function findSubseq(s) {
let n = s.length;
let st = new Set();
// Find all valid subsequences using recursion
findSubsequences(0, n, s, "", st);
// Convert set to sorted array for return
return [...st].sort();}
// Driver code let s = "abc"; let result = findSubseq(s); console.log(result.join(' '));
`
[Expected Approach] Using Bit Masking - O(n * 2^n) Time and O(n * 2^n) Space
The idea is to use a bitmask to represent every possible subsequence of the string. For a string of length n there are 2^n possible subsequences. Each bit in the mask from 0 to 2^n - 1 represents whether the character at that position is included or not. For each mask we build the corresponding subsequence and check if it starts with a vowel and ends with a consonant. We use a set to handle duplicates and maintain lexicographic order automatically.
C++ `
#include #include #include #include using namespace std;
bool isVowel(char ch) { return ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u'; }
vector findSubseq(string s) {
int n = s.length();
set<string> st;
// Iterate over all possible bitmasks from 1 to 2^n - 1
for (int mask = 1; mask < (1 << n); mask++)
{
string current = "";
// Build subsequence based on set bits in mask
for (int i = 0; i < n; i++)
{
if (mask & (1 << i))
current += s[i];
}
// Add if starts with vowel and ends with consonant
if (isVowel(current[0]) && !isVowel(current.back()))
st.insert(current);
}
// Convert set to vector for return
return vector<string>(st.begin(), st.end());}
int main() { string s = "abc"; vector result = findSubseq(s); for (int i = 0; i < result.size(); i++) { if (i != 0) cout << " "; cout << result[i]; } cout << endl; return 0; }
Java
import java.util.ArrayList; import java.util.TreeSet;
class GFG {
static boolean isVowel(char ch) {
return ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u';
}
static ArrayList<String> findSubseq(String s) {
int n = s.length();
TreeSet<String> st = new TreeSet<>();
// Iterate over all possible bitmasks from 1 to 2^n - 1
for (int mask = 1; mask < (1 << n); mask++) {
StringBuilder current = new StringBuilder();
// Build subsequence based on set bits in mask
for (int i = 0; i < n; i++) {
if ((mask & (1 << i)) != 0)
current.append(s.charAt(i));
}
// Add if starts with vowel and ends with consonant
String curr = current.toString();
if (isVowel(curr.charAt(0)) && !isVowel(curr.charAt(curr.length() - 1)))
st.add(curr);
}
// Convert TreeSet to ArrayList for return
return new ArrayList<>(st);
}
public static void main(String[] args) {
String s = "abc";
ArrayList<String> result = findSubseq(s);
System.out.println(String.join(" ", result));
}}
Python
def isVowel(ch): return ch in 'aeiou'
def findSubseq(s):
n = len(s)
st = set()
# Iterate over all possible bitmasks from 1 to 2^n - 1
for mask in range(1, 1 << n):
current = ""
# Build subsequence based on set bits in mask
for i in range(n):
if mask & (1 << i):
current += s[i]
# Add if starts with vowel and ends with consonant
if isVowel(current[0]) and not isVowel(current[-1]):
st.add(current)
# Convert set to sorted list for return
return sorted(st)if name == "main": s = "abc" result = findSubseq(s) print(' '.join(result))
C#
using System; using System.Collections.Generic;
class GFG {
static bool isVowel(char ch) {
return ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u';
}
static List<string> findSubseq(string s) {
int n = s.Length;
SortedSet<string> st = new SortedSet<string>();
// Iterate over all possible bitmasks from 1 to 2^n - 1
for (int mask = 1; mask < (1 << n); mask++) {
string current = "";
// Build subsequence based on set bits in mask
for (int i = 0; i < n; i++) {
if ((mask & (1 << i)) != 0)
current += s[i];
}
// Add if starts with vowel and ends with consonant
if (isVowel(current[0]) && !isVowel(current[current.Length - 1]))
st.Add(current);
}
// Convert SortedSet to List for return
return new List<string>(st);
}
static void Main() {
string s = "abc";
List<string> result = findSubseq(s);
Console.WriteLine(string.Join(" ", result));
}}
JavaScript
function isVowel(ch) { return 'aeiou'.includes(ch); }
function findSubseq(s) {
let n = s.length;
let st = new Set();
// Iterate over all possible bitmasks from 1 to 2^n - 1
for (let mask = 1; mask < (1 << n); mask++) {
let current = "";
// Build subsequence based on set bits in mask
for (let i = 0; i < n; i++) {
if (mask & (1 << i))
current += s[i];
}
// Add if starts with vowel and ends with consonant
if (isVowel(current[0]) && !isVowel(current[current.length - 1]))
st.add(current);
}
// Convert set to sorted array for return
return [...st].sort();}
// Driver code let s = "abc"; let result = findSubseq(s); console.log(result.join(' '));
`