Print all Subsequences of String which Start with Vowel and End with Consonant.

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.

Try It Yourself
redirect icon

[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 <iostream>
#include <set>
#include <string>
#include <vector>
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 &current, set<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.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<string> 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<string> 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(' '));

Output
ab abc ac

[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 <iostream>
#include <set>
#include <string>
#include <vector>
using namespace std;

bool isVowel(char ch)
{
    return ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u';
}

vector<string> 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<string> 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(' '));

Output
ab abc ac
Comment