Find substrings that contain all vowels

Last Updated : 11 Feb, 2025

Given a string s containing lowercase alphabets, the task is to print the sub-strings that contain all the vowels at-least one time and there are no consonants (non-vowel characters) present in the sub-strings. 

Examples:  

Input: s = "aeoibsddaaeiouudb" 
Output: ["aaeiouu", "aeiouu", "aeiou", "aaeiou"]
Explanation: The 4 distinct substrings containing all the vowels in order are "aaeiouu", "aeiouu", "aeiou", and "aaeiou".

Input: s = "aeoisdiouuae" 
Output: ["iouuae"]
Explanation: Only one substring "iouuae" contains all the vowels in order.

Generate all Substrings - O(n^2) Time and O(1) Space

The idea behind this code is to find all substrings of the input string that contain all the vowels ('a', 'e', 'i', 'o', 'u'). The approach is to iterate over all possible starting points of substrings in the given string. For each starting point, we explore all possible ending points to form substrings. As we form each substring, we check whether all its characters are vowels, breaking the loop immediately if a consonant is encountered since only vowel-only substrings are valid. While processing each valid substring, we track the count of each vowel. If all vowels are present in the current substring, we add it to the result. Finally, we return the result containing all valid substrings

Below is the implementation of the above approach:

C++
// C++ program to find substrings that 
// contain all vowels
#include <bits/stdc++.h>
using namespace std;

// Function to check if all vowels are present
bool containsAllVowels(vector<int>& vowelCount) {
  
    // Check if all vowels are found
    for (int i = 0; i < 5; i++) {
        if (vowelCount[i] == 0) return false;
    }
    return true;
}

// Function to count valid vowel-only 
// substrings and store them
vector<string> countVowelSubstrings(string& s) {
    vector<string> result;
    int n = s.length();

    // Iterate over all possible starting points
    for (int i = 0; i < n; i++) {
        vector<int> vowelCount(5, 0);  
        int cnt = 0;
        string curr = "";

        // Iterate over possible ending points 
        // of substrings
        for (int j = i; j < n; j++) {
            char ch = s[j];

            // If consonant found, break the loop
            if (ch != 'a' && ch != 'e' && ch != 'i' 
                && ch != 'o' && ch != 'u') {
                break;
            }

            // Append the character to the current substring
            curr += ch;

            // Increment vowel count for the found vowel
            if (ch == 'a') vowelCount[0]++;
            else if (ch == 'e') vowelCount[1]++;
            else if (ch == 'i') vowelCount[2]++;
            else if (ch == 'o') vowelCount[3]++;
            else if (ch == 'u') vowelCount[4]++;

            // If all vowels are present, store the substring
            if (containsAllVowels(vowelCount)) {
                result.push_back(curr);
            }
        }
    }

    return result;
}

void printArr(vector<string>& substrings) {
    for (string& s : substrings) {
        cout << s << endl;
    }
}

int main() {
  
    string s = "aeoibsddaaeiouudb";
    
    // Get the result of valid 
    // vowel-only substrings
    vector<string> result 
                = countVowelSubstrings(s);
   
    printArr(result);

    return 0;
}
Java
// Java program to find substrings that 
// contain all vowels
import java.util.*;

class GfG {

    // Function to check if all vowels are present
    static boolean containsAllVowels(int[] vowelCount) {
        
        // Check if all vowels are found
        for (int i = 0; i < 5; i++) {
            if (vowelCount[i] == 0) {
                return false;
            }
        }
        return true;
    }

    // Function to count valid vowel-only 
    // substrings and store them
    static List<String> countVowelSubstrings(String s) {
        List<String> result = new ArrayList<>();
        int n = s.length();

        // Iterate over all possible starting points
        for (int i = 0; i < n; i++) {
            int[] vowelCount = new int[5];
            StringBuilder curr = new StringBuilder();

            // Iterate over possible ending points 
            // of substrings
            for (int j = i; j < n; j++) {
                char ch = s.charAt(j);

                // If consonant found, break the loop
                if (ch != 'a' && ch != 'e' && ch != 'i' 
                    && ch != 'o' && ch != 'u') {
                    break;
                }

                // Append the character to the current substring
                curr.append(ch);

                // Increment vowel count for the found vowel
                if (ch == 'a') vowelCount[0]++;
                else if (ch == 'e') vowelCount[1]++;
                else if (ch == 'i') vowelCount[2]++;
                else if (ch == 'o') vowelCount[3]++;
                else if (ch == 'u') vowelCount[4]++;

                // If all vowels are present, store the substring
                if (containsAllVowels(vowelCount)) {
                    result.add(curr.toString());
                }
            }
        }

        return result;
    }

    static void printArr(List<String> substrings) {
        for (String s : substrings) {
            System.out.println(s);
        }
    }

    public static void main(String[] args) {
        
        String s = "aeoibsddaaeiouudb";
        
        // Get the result of valid 
        // vowel-only substrings
        List<String> result = countVowelSubstrings(s);
        
        printArr(result);
    }
}
Python
# Python program to find substrings that 
# contain all vowels

# Function to check if all vowels are present
def containsAllVowels(vowelCount):
    
    # Check if all vowels are found
    for i in range(5):
        if vowelCount[i] == 0:
            return False
    return True

# Function to count valid vowel-only 
# substrings and store them
def countVowelSubstrings(s):
    result = []
    n = len(s)

    # Iterate over all possible starting points
    for i in range(n):
        vowelCount = [0] * 5
        curr = ""

        # Iterate over possible ending points 
        # of substrings
        for j in range(i, n):
            ch = s[j]

            # If consonant found, break the loop
            if ch not in 'aeiou':
                break

            # Append the character to the current substring
            curr += ch

            # Increment vowel count for the found vowel
            if ch == 'a':
                vowelCount[0] += 1
            elif ch == 'e':
                vowelCount[1] += 1
            elif ch == 'i':
                vowelCount[2] += 1
            elif ch == 'o':
                vowelCount[3] += 1
            elif ch == 'u':
                vowelCount[4] += 1

            # If all vowels are present, store the substring
            if containsAllVowels(vowelCount):
                result.append(curr)

    return result

def printArr(substrings):
    for s in substrings:
        print(s)

if __name__ == "__main__":
    
    s = "aeoibsddaaeiouudb"
    
    # Get the result of valid 
    # vowel-only substrings
    result = countVowelSubstrings(s)
    
    printArr(result)
C#
// C# program to find substrings that 
// contain all vowels
using System;
using System.Collections.Generic;

class GfG {

    // Function to check if all vowels are present
    static bool ContainsAllVowels(int[] vowelCount) {
        
        // Check if all vowels are found
        for (int i = 0; i < 5; i++) {
            if (vowelCount[i] == 0) {
                return false;
            }
        }
        return true;
    }

    // Function to count valid vowel-only 
    // substrings and store them
    static List<string> CountVowelSubstrings(string s) {
        List<string> result = new List<string>();
        int n = s.Length;

        // Iterate over all possible starting points
        for (int i = 0; i < n; i++) {
            int[] vowelCount = new int[5];
            string curr = "";

            // Iterate over possible ending points 
            // of substrings
            for (int j = i; j < n; j++) {
                char ch = s[j];

                // If consonant found, break the loop
                if (ch != 'a' && ch != 'e' && ch != 'i' 
                    && ch != 'o' && ch != 'u') {
                    break;
                }

                // Append the character to the current substring
                curr += ch;

                // Increment vowel count for the found vowel
                if (ch == 'a') vowelCount[0]++;
                else if (ch == 'e') vowelCount[1]++;
                else if (ch == 'i') vowelCount[2]++;
                else if (ch == 'o') vowelCount[3]++;
                else if (ch == 'u') vowelCount[4]++;

                // If all vowels are present, store the substring
                if (ContainsAllVowels(vowelCount)) {
                    result.Add(curr);
                }
            }
        }

        return result;
    }

    static void PrintArr(List<string> substrings) {
        foreach (string s in substrings) {
            Console.WriteLine(s);
        }
    }

    static void Main(string[] args) {
        
        string s = "aeoibsddaaeiouudb";
        
        // Get the result of valid 
        // vowel-only substrings
        List<string> result = CountVowelSubstrings(s);
        
        PrintArr(result);
    }
}
JavaScript
// JavaScript program to find substrings that 
// contain all vowels

// Function to check if all vowels are present
function containsAllVowels(vowelCount) {

    // Check if all vowels are found
    for (let i = 0; i < 5; i++) {
        if (vowelCount[i] === 0) {
            return false;
        }
    }
    return true;
}

// Function to count valid vowel-only 
// substrings and store them
function countVowelSubstrings(s) {
    let result = [];
    let n = s.length;

    // Iterate over all possible starting points
    for (let i = 0; i < n; i++) {
        let vowelCount = Array(5).fill(0);
        let curr = "";

        // Iterate over possible ending points 
        // of substrings
        for (let j = i; j < n; j++) {
            let ch = s[j];

            // If consonant found, break the loop
            if (ch !== 'a' && ch !== 'e' && ch !== 'i' 
                && ch !== 'o' && ch !== 'u') {
                break;
            }

            // Append the character to the current substring
            curr += ch;

            // Increment vowel count for the found vowel
            if (ch === 'a') vowelCount[0]++;
            else if (ch === 'e') vowelCount[1]++;
            else if (ch === 'i') vowelCount[2]++;
            else if (ch === 'o') vowelCount[3]++;
            else if (ch === 'u') vowelCount[4]++;

            // If all vowels are present, store the substring
            if (containsAllVowels(vowelCount)) {
                result.push(curr);
            }
        }
    }

    return result;
}

function printArr(substrings) {
    for (let s of substrings) {
        console.log(s);
    }
}

let s = "aeoibsddaaeiouudb";

// Get the result of valid 
// vowel-only substrings
let result = countVowelSubstrings(s);

printArr(result);

Output
aaeiou
aaeiouu
aeiou
aeiouu

Time Complexity: O(n^2), for generating all substrings and checking vowels.
Auxiliary Space: O(1), as apart from input and output we are using constant extra space.

Using Sliding Window - O(n) Time and O(1) Space

The idea is to use a sliding window approach to find substrings containing all the vowels ('a', 'e', 'i', 'o', 'u'). The sliding window dynamically adjusts by maintaining a frequency map of vowels within the window. As we traverse the string, we check if the current character is a vowel and update the frequency map while counting unique vowels in the window. When all vowels are present, we add valid substrings ending at the current position to the result. If a non-vowel character is encountered, the window is reset, and we start from the next position. Throughout, the window is adjusted to remove duplicate vowels while ensuring the substring remains valid. This process continues until all possible substrings are evaluated.

Below is the implementation of the above approach:

C++
// C++ program to find substrings that 
// contain all vowels using sliding window
#include <bits/stdc++.h>
using namespace std;

// Function to count substrings with all vowels
vector<string> countVowelSubstrings(string& s) {
  
    unordered_map<char, int> freq; 
    int n = s.size();
    vector<string> result;  
    int vowelCount = 0, prefixCount = 0, j = 0;

    // Sliding window approach
    for (int i = 0; i < n; i++) {
        char ch = s[i];

        // Check if character is a vowel
        if (ch == 'a' || ch == 'e' || ch == 'i' 
            || ch == 'o' || ch == 'u') {

            // Increment frequency for current vowel
            if (++freq[ch] == 1) {
                vowelCount++;
            }

            // Adjust window to avoid duplicate vowels
            while (freq[s[j]] > 1) {
                freq[s[j]]--;
                prefixCount++;
                j++;
            }

            // If all vowels are present, collect substrings
            if (vowelCount == 5) {
                for (int k = 0; k <= prefixCount; k++) {
                    result.push_back(s.substr(j - k,
                                              i - (j - k) + 1));
                }
            }
        } else {
          
            // Reset for non-vowel characters
            vowelCount = 0;
            prefixCount = 0;
            freq.clear();
            j = i + 1;
        }
    }

    return result;
}

// Function to print substrings
void printArr(vector<string>& substrings) {
    for (string& substring : substrings) {
        cout << substring << endl;
    }
}

int main() {
  
    string s = "aeoibsddaaeiouudb";

    // Get the result of valid vowel-only substrings
    vector<string> result = countVowelSubstrings(s);

    printArr(result);

    return 0;
}
Java
// Java program to find substrings that 
// contain all vowels using sliding window
import java.util.*;

class GfG {

    // Function to count substrings with all vowels
    public static List<String> countVowelSubstrings(String s) {
  
        HashMap<Character, Integer> freq = new HashMap<>();
        int n = s.length();
        List<String> result = new ArrayList<>();
        int cnt = 0, pref = 0, j = 0;

        // Sliding window approach
        for (int i = 0; i < n; i++) {
            char ch = s.charAt(i);

            // Check if character is a vowel
            if (ch == 'a' || ch == 'e' || ch == 'i' 
                || ch == 'o' || ch == 'u') {

                // Increment frequency for current vowel
                freq.put(ch, freq.getOrDefault(ch, 0) + 1);
                if (freq.get(ch) == 1) {
                    cnt++;
                }

                // Adjust window to avoid duplicate vowels
                while (freq.get(s.charAt(j)) > 1) {
                    freq.put(s.charAt(j), freq.get(s.charAt(j)) - 1);
                    pref++;
                    j++;
                }

                // If all vowels are present, collect substrings
                if (cnt == 5) {
                  
                    // Add valid substrings
                    for (int k = 0; k <= pref; k++) {
                        int startIndex = j - k;
                        int endIndex = i + 1;
                      
                        if (startIndex < endIndex) {
                            result.add(s.substring(startIndex, endIndex));
                        }
                    }
                }
            } else {
              
                // Reset for non-vowel characters
                cnt = 0;
                pref = 0;
                freq.clear();
                j = i + 1;
            }
        }

        return result;
    }

    // Function to print substrings
    public static void printArr(List<String> substrings) {
        for (String s : substrings) {
            System.out.println(s);
        }
    }

    public static void main(String[] args) {
  
        String s = "aeoibsddaaeiouudb";

        // Get the result of valid vowel-only substrings
        List<String> result = countVowelSubstrings(s);

        printArr(result);
    }
}
Python
# Python program to find all substrings that 
# contain all vowels using Sliding Window

# Function to count substrings with all vowels
def countVowelSubstrings(s):
    freq = {}
    n = len(s)
    result = []
    cnt = 0
    pref = 0
    j = 0

    # Sliding window approach
    for i in range(n):
        ch = s[i]

        # Check if character is a vowel
        if ch in 'aeiou':

            # Increment frequency for current vowel
            if ch in freq:
                freq[ch] += 1
            else:
                freq[ch] = 1

            if freq[ch] == 1:
                cnt += 1

            # Adjust window to avoid duplicate vowels
            while freq[s[j]] > 1:
                freq[s[j]] -= 1
                pref += 1
                j += 1

            # If all vowels are present, collect substrings
            if cnt == 5:
              
                # Add valid substrings
                for k in range(pref + 1):
                    result.append(s[j - k:i + 1])

        else:
          
            # Reset for non-vowel characters
            cnt = 0
            pref = 0
            freq.clear()
            j = i + 1

    return result

def printArr(substrings):
    for s in substrings:
        print(s)

if __name__ == "__main__":
  
    s = "aeoibsddaaeiouudb"

    # Get the result of valid vowel-only substrings
    result = countVowelSubstrings(s)

    printArr(result)
C#
// C# program to find substrings that 
// contain all vowels using sliding window
using System;
using System.Collections.Generic;

class GfG {

    // Function to count substrings with all vowels
    public static List<string> countVowelSubstrings(string s) {
  
        Dictionary<char, int> freq = new Dictionary<char, int>();
        int n = s.Length;
        List<string> result = new List<string>();
        int cnt = 0, pref = 0, j = 0;

        // Sliding window approach
        for (int i = 0; i < n; i++) {
            char ch = s[i];

            // Check if character is a vowel
            if (ch == 'a' || ch == 'e' || ch == 'i' 
                || ch == 'o' || ch == 'u') {

                // Increment frequency for current vowel
                if (freq.ContainsKey(ch)) {
                    freq[ch]++;
                } else {
                    freq[ch] = 1;
                }

                if (freq[ch] == 1) {
                    cnt++;
                }

                // Adjust window to avoid duplicate vowels
                while (freq[s[j]] > 1) {
                    freq[s[j]]--;
                    pref++;
                    j++;
                }

                // If all vowels are present, collect substrings
                if (cnt == 5) {
                  
                    // Add valid substrings
                    for (int k = 0; k <= pref; k++) {
                        int startIndex = j - k;
                        int endIndex = i + 1;
                      
                        if (startIndex < endIndex) {
                            result.Add(s.Substring(startIndex,
                                                   endIndex - startIndex));
                        }
                    }
                }
            } else {
              
                // Reset for non-vowel characters
                cnt = 0;
                pref = 0;
                freq.Clear();
                j = i + 1;
            }
        }

        return result;
    }

    // Function to print substrings
    public static void printArr(List<string> substrings) {
        foreach (string s in substrings) {
            Console.WriteLine(s);
        }
    }

    public static void Main() {
  
        string s = "aeoibsddaaeiouudb";

        // Get the result of valid vowel-only substrings
        List<string> result = countVowelSubstrings(s);

        printArr(result);
    }
}
JavaScript
// JavaScript program to find all substrings that 
// contain all vowels using Sliding Window
    
// Function to count substrings with all vowels
function countVowelSubstrings(s) {
    let freq = {};
    let n = s.length;
    let result = [];
    let cnt = 0, pref = 0, j = 0;

    // Sliding window approach
    for (let i = 0; i < n; i++) {
        let ch = s[i];

        // Check if character is a vowel
        if ('aeiou'.includes(ch)) {

            // Increment frequency for current vowel
            freq[ch] = (freq[ch] || 0) + 1;

            if (freq[ch] === 1) {
                cnt++;
            }

            // Adjust window to avoid duplicate vowels
            while (freq[s[j]] > 1) {
                freq[s[j]]--;
                pref++;
                j++;
            }

            // If all vowels are present, collect substrings
            if (cnt === 5) {
            
                // Add valid substrings
                for (let k = 0; k <= pref; k++) {
                    result.push(s.substring(j - k, i + 1));
                }
            }
        } else {
        
            // Reset for non-vowel characters
            cnt = 0;
            pref = 0;
            freq = {};
            j = i + 1;
        }
    }

    return result;
}

function printArr(substrings) {
    substrings.forEach(s => {
        console.log(s);
    });
}

let s = "aeoibsddaaeiouudb";

// Get the result of valid vowel-only substrings
let result = countVowelSubstrings(s);

printArr(result);

Output
aeiou
aaeiou
aeiouu
aaeiouu

Time Complexity: O(n), as we are iterating through the string once, and each character is processed in constant time.
Auxiliary Space: O(1), since we are using a fixed-size frequency map (for vowels).    

Comment