Skip to content
Related Articles

Related Articles

Improve Article

Longest Ordered Subsequence of Vowels

  • Difficulty Level : Hard
  • Last Updated : 09 Aug, 2021

Given a string consisting of only vowels, find the longest subsequence in the given string such that it consists of all five vowels and is a sequence of one or more a’s, followed by one or more e’s, followed by one or more i’s, followed by one or more o’s and followed by one or more u’s. 

If there is more than one longest subsequence, print any one.

Examples:  

Input :  str = "aeiaaioooaauuaeiou" 
Output :  {a, a, a, a, a, a, e, i, o, u}
There are two possible outputs in this case: 
{a, a, a, a, a, a, e, i, o, u} and, 
{a, e, i, i, o, o, o, u, u, u}
each of length 10

Input : str = "aaauuiieeou"
Output : No subsequence possible

Approach: 
We loop through all the characters in the string recursively and follow the given conditions: 

  1. If the subsequence is empty, we include the vowel at the current index only if it is ‘a’. Otherwise, we move on to the next index.
  2. If the vowel at the current index is same as the last vowel included in the subsequence, we include it.
  3. If the vowel at the current index is the next possible vowel (i.e a–> e–> i–> o–> u ) after the last vowel included in the subsequence, we have two options: either include it or move on to the next index. Hence we choose the one which gives the longest subsequence.
  4. If none of the above conditions is satisfied, we move on to the next index (to avoid invalid ordering of vowels in the subsequence).
  5. If we have reached the end of the string, we check if the current subsequence is valid or not. If it is valid (i.e if it contains all the vowels), we return it, else we return an empty list.

Method 1 



Below is the implementation of the above approach:  

C++




// C++ program to find the longest subsequence
// of vowels in the specified order
#include <bits/stdc++.h>
using namespace std;
 
vector<char> vowels = { 'a', 'e', 'i', 'o', 'u' };
 
// Mapping values for vowels
map<char, int> mapping = { { 'a', 0 }, { 'e', 1 },
                           { 'i', 2 }, { 'o', 3 },
                           { 'u', 4 } };
  
// Function to check if given subsequence
// contains all the vowels or not
bool isValidSequence(string subList)
{
    for(char c : vowels)
    {
         
        // not contain vowel
        if (subList.find(c) == std::string::npos)
            return 0;
    
    return 1;
}
 
// Function to find the longest subsequence
// of vowels in the given string in specified
// order
string longestSubsequence(string str,
                          string subList,
                          int index)
{
     
    // If we have reached the end of the
    // string, return the subsequence
    // if it is valid, else return an
    // empty list
    int len = str.length();
     
    if (index >= len)
    {
        if (isValidSequence(subList))
            return subList;
        else
            return "";
    }
     
    // If there is no vowel in the
    // subsequence yet, add vowel
    // at current index if it is 'a',
    // else move on to the next character
    // in the string 
    else if (subList.size() == 0)
   {
       if (str[index] != 'a')
         return longestSubsequence(
             str, "", index + 1);
       else
         return longestSubsequence(
             str, subList + str[index],
                    index + 1);
   }
    
    //  If the last vowel in the subsequence
    // until now is same as the vowel at
    // current index, add it to the subsequence
    else if (mapping[subList[subList.size() - 1]] ==
             mapping[str[index]])
        return longestSubsequence(
            str, subList+str[index], index + 1);
     
    // If the vowel at the current index comes
    // right after the last vowel in the
    // subsequence, we have two options:
    // either to add the vowel in the
    // subsequence, or move on to next character.
    // We choose the one which gives the longest
    // subsequence.
    else if (mapping[subList[subList.size() - 1]] + 1 ==
             mapping[str[index]])
    {
        string sub1 = longestSubsequence(
            str, subList + str[index], index + 1);
        string sub2 = longestSubsequence(
            str, subList, index + 1);
         
        if (sub1.length() > sub2.length())
            return sub1;
        else
            return sub2;
    }   
    else
        return longestSubsequence(
            str, subList, index + 1);    
}
 
// Driver Code
int main()
{
    string  str= "aeiaaioooauuaeiou";
     
    string subsequence = longestSubsequence(
        str, "", 0);
         
    if (subsequence.length() == 0)
        cout << "No subsequence possible\n";
    else
        cout << subsequence << "\n";
}
 
// This code is contributed by ajaykr00kj

Python3




# Python3 program to find the longest subsequence
# of vowels in the specified order
 
vowels = ['a', 'e', 'i', 'o', 'u']
 
# Mapping values for vowels
mapping = {'a': 0, 'e': 1, 'i': 2, 'o': 3, 'u': 4}
 
# Function to check if given subsequence
# contains all the vowels or not
def isValidSequence(subList):
     
    for vowel in vowels:
        if vowel not in subList:
            return False
             
    return True
 
# Function to find the longest subsequence of vowels
# in the given string in specified order
def longestSubsequence(string, subList, index):
     
    # If we have reached the end of the string,
    # return the subsequence
    # if it is valid, else return an empty list
    if index == len(string):
        if isValidSequence(subList) == True:
            return subList
        else:
            return []
         
    else:
        # If there is no vowel in the subsequence yet,
        # add vowel at current index if it is 'a',
        # else move on to the next character
        # in the string
        if len(subList) == 0:
             
            if string[index] != 'a':
                return longestSubsequence(string, subList, index + 1)
            else:
                return longestSubsequence(string, subList + \
                            [string[index]], index + 1)
         
        # If the last vowel in the subsequence until
        # now is same as the vowel at current index,
        # add it to the subsequence
        elif mapping[subList[-1]] == mapping[string[index]]:
            return longestSubsequence(string, subList + \
                            [string[index]], index + 1)
         
        # If the vowel at the current index comes
        # right after the last vowel
        # in the subsequence, we have two options:
        # either to add the vowel in
        # the subsequence, or move on to next character.
        # We choose the one which gives the longest subsequence.
        elif (mapping[subList[-1]] + 1) == mapping[string[index]]:
             
            sub1 = longestSubsequence(string, subList + \
                                [string[index]], index + 1)
            sub2 = longestSubsequence(string, subList, index + 1)
             
            if len(sub1) > len(sub2):
                return sub1
            else:
                return sub2
                 
        else:
            return longestSubsequence(string, subList, index + 1)
 
# Driver Code
if __name__ == "__main__":
         
    string = "aeiaaioooauuaeiou"
     
    subsequence = longestSubsequence(string, [], 0)
    if len(subsequence) == 0:
        print("No subsequence possible")
    else:
        print(subsequence)
                                                
Output: 
['a', 'e', 'i', 'i', 'o', 'o', 'o', 'u', 'u', 'u']

 

 
Method 2 (Dynamic Programming)

Python3




from random import choice
 
def longest_subsequence(string):
    def helper(chosen="", i=0):
        if i == len(string):
            return chosen if set("aeiou").issubset(set(chosen)) else ""
 
        hashable = (chosen[-1] if chosen else None, len(chosen), i)
 
        if hashable in memo:
            return memo[hashable]
 
        if not chosen:
            res = helper("a" if string[i] == "a" else chosen, i + 1)
        elif chosen[-1] == string[i]:
            res = helper(chosen + string[i], i + 1)
        elif mapping[chosen[-1]] + 1 == mapping[string[i]]:
            sub1 = helper(chosen + string[i], i + 1)
            sub2 = helper(chosen, i + 1)
 
            res = sub1 if len(sub1) > len(sub2) else sub2
        else:
            res = helper(chosen, i + 1)
 
        memo[hashable] = res
        return res
 
    mapping = {x: i for i, x in enumerate("aeiou")}
    memo = {}
    return helper()
 
 
if __name__ == "__main__":
    tests = [
        "aeiaaioooaauuaeiou",
        "aaauuiieeou",
        "".join(choice("aeiou") for _ in range(40)),
        "".join(choice("aeiou") for _ in range(900))
    ]
     
    for string in tests:
        print("original:", string)
        subsequence = longest_subsequence(string)
         
        if subsequence:
            print("\nmax subsequence:", "".join(subsequence))
        else:
            print("No subsequence possible")
 
        print("-" * 40, "\n")
Output: 
original: aeiaaioooaauuaeiou

max subsequence: aaaaaaeiou
---------------------------------------- 

original: aaauuiieeou
No subsequence possible
---------------------------------------- 

original: auaaioeoiaooaauoeuaueouuoeiiooiiaiiuioio

max subsequence: aaaaaaeeeiioou
---------------------------------------- 

original: eaaioeaieoaiueiuiaeiuueeueouoiuueeuaooooiuaiaeuaaieiauaiauuieaoeeeieeoiuaiuuuaaoieooooeioeiouuaoeaouooiauiuiioaoeeeuaoeooiueoaiuioeaeaaouiiiauiuuauoiaiaauaeooeuaiuoeeaaeoaiaoiueieeuaioieouuaaiieeaaeiioaoieoauieoueoauaieueoaeiaoaeoeuiaiauuauouoouaeaueeeioauaieiaieoaeiiueuaaoeuoiueaaiaiaouoouueoauoeieaioeeuueiaaoaiaiiaiueuauaeaieuioooiaeooeaueeoueiueeaueuuiaeuoiuiaeioeeuoaiuueuiaaueueuaeoueuaiaiiuiaouoiueuuueeaueeoaiaaouuiioeioeiaaiieaieiiieeeiaaoaeoououaooiioieuoaeaueuoeaueaoaieeeeauouaaaeiiuoiiuieuuoouuaaoiuaiaoaeeeeiauuuuoiuuoeiieuoaeaouaaooiuuuaeaeaeioeuuauaeaioiuuueuuiuieoieooeoiuioeouuuuaooeueaiooaeiieeieuauoeoaieaeiaaeeoiieiaeuouuuuououiuaueoeooaaeeuuiiaiiueoueaaauaiaieiuiiieauaaioauiuoiiiaieeuaieieiuooeaeooooeouioaooieooeaaaeeeuouiiooiaiieeeuoieeuueouiuuoioeeoiuaauuaaeaueeeiuuuueeeaaeuuoeeeuuieeueeuiaeioeaoiiiiauuoeieeioooaoaeueouiaoeouioaueoaioiuoieuoueuiuouiuaiiaeiuueaiaeuaaeouoa

max subsequence: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeiiiiiiiiiiiiiiiiiiiooooooooooooooouuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
----------------------------------------

 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :