Open In App

Count substrings that contain all vowels | SET 2

Last Updated : 11 Feb, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a string str containing lowercase alphabets, the task is to count 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: str = "aeoibsddaaeiouudb" 
Output:
Explanation: The 4 distinct substrings containing all the vowels in order are "aaeiouu", "aeiouu", "aeiou", and "aaeiou".

Input: str = "aeoisbddiouuaedf" 
Output: 1
Explanation: Only one substring "iouuae" contains all the vowels in order.

Input: str = "aeouisddaaeeiouua" 
Output:
Explanation: There are 9 distinct substrings containing all vowels in order in the given string.

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

The idea is to iterate over all possible substrings of the input string and check if each substring contains all the vowels ('a', 'e', 'i', 'o', 'u'). For each substring, a count is maintained for each vowel. If all vowels are found in a substring, it is considered valid, and the count is incremented. The process stops as soon as a consonant is encountered in a substring, as only vowel-only substrings are valid.

Below is the implementation of the above approach:

C++
// C++ implementation to count substrings 
// that contains 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
int countVowelSubstrings(string& str) {
    int count = 0;
    int n = str.length();

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

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

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

            // 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, count 
            // the substring
            if (containsAllVowels(vowelCount)) {
                count++;
            }
        }
    }

    return count;
}

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

    cout << countVowelSubstrings(str);

    return 0;
}
Java
// Java implementation to count substrings
// that contains all vowels
import java.util.ArrayList;

class GfG {

    // Function to check if all vowels are present
    public static boolean containsAllVowels(
        ArrayList<Integer> vowelCount) {

        // Check if all vowels are found
        for (int i = 0; i < 5; i++) {
            if (vowelCount.get(i) == 0) return false;
        }
        return true;
    }

    // Function to count valid vowel-only substrings
    static int countVowelSubstrings(String str) {
        int count = 0;
        int n = str.length();

        // Iterate over all possible starting points
        for (int i = 0; i < n; i++) {
            ArrayList<Integer> vowelCount 
                                 = new ArrayList<>(5);

            // Initialize vowel count list with 0
            for (int j = 0; j < 5; j++) {
                vowelCount.add(0);
            }

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

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

                // Increment vowel count for the found vowel
                if (ch == 'a') vowelCount.set(0,
                    vowelCount.get(0) + 1);

                else if (ch == 'e') vowelCount.set(1,
                    vowelCount.get(1) + 1);
              
                else if (ch == 'i') vowelCount.set(2,
                    vowelCount.get(2) + 1);
              
                else if (ch == 'o') vowelCount.set(3,
                    vowelCount.get(3) + 1);
              
                else if (ch == 'u') vowelCount.set(4,
                    vowelCount.get(4) + 1);

                // If all vowels are present, count the substring
                if (containsAllVowels(vowelCount)) {
                    count++;
                }
            }
        }

        return count;
    }

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

        System.out.println(countVowelSubstrings(str));
    }
}
Python
# Python implementation to count substrings 
# that contains all vowels

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

def countVowelSubstrings(str):
    count = 0
    n = len(str)

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

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

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

            # 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, count the substring
            if containsAllVowels(vowelCount):
                count += 1

    return count


if __name__ == "__main__":
  
    str = "aeoibsddaaeiouudb"
    
    print(countVowelSubstrings(str))
C#
// C# implementation to count substrings
// that contains all vowels
using System;
using System.Collections.Generic;

class GfG {
  
    // Function to check if all vowels are present
    static bool ContainsAllVowels(List<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
    static int CountVowelSubstrings(string str) {
        int count = 0;
        int n = str.Length;

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

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

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

                // 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, count 
                // the substring
                if (ContainsAllVowels(vowelCount)) {
                    count++;
                }
            }
        }

        return count;
    }

    public static void Main(string[] args) {
      
        string str = "aeoibsddaaeiouudb";

        Console.WriteLine(CountVowelSubstrings(str));
    }
}
JavaScript
// JavaScript implementation to count substrings
// that contains all vowels

// Function to check if all vowels
// are found
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 countVowelSubstrings(str) {
    let count = 0;
    let n = str.length;

    // Iterate over all possible starting points
    for (let i = 0; i < n; i++) {
        let vowelCount = [0, 0, 0, 0, 0];

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

            // If consonant is found, break the loop
            if (!'aeiou'.includes(ch)) {
                break;
            }

            // 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, count the substring
            if (containsAllVowels(vowelCount)) {
                count++;
            }
        }
    }

    return count;
}

let str = "aeoibsddaaeiouudb";

console.log(countVowelSubstrings(str));

Output
4

Time Complexity: O(n^2), for generating all substrings and constant time for checking vowels.
Auxiliary Space: O(1), for tracking vowels and substring building.

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

The idea is to use a sliding window approach, the sliding window is maintained using two pointers and a frequency map to track the counts of vowels within the window.

  • As we iterate through the string, we check if each character is a vowel and update its count in the frequency map.
  • If a vowel is found, we track how many unique vowels are present in the current window. To ensure the window is valid, we adjust its size by moving the start pointer when duplicate vowels are encountered.
  • If all vowels are present, the count is updated by adding the possible valid substrings that can end at the current position.
  • The process resets whenever a non-vowel character is encountered, starting a new window from the next position.
  • This ensures we efficiently count all valid substrings containing all vowels, avoiding unnecessary processing of invalid substrings.

Below is the implementation of the above approach:

C++
// C++ implementation to count substrings that 
// contains all vowels using Sliding Window
#include <bits/stdc++.h>
using namespace std;

// Function to count vowel substrings
int countVowelSubstrings(string str) {
    unordered_map<char, int> freq;
    int n = str.size();
    int ans = 0;

    // Sliding window approach
    for (int i = 0, cnt = 0, j = 0, 
                  pref = 0; i < n; i++) {
      
        char ch = str[i];

        // Check if character is a vowel
        if (ch == 'a' || ch == 'e' || ch == 'i' 
                  || ch == 'o' || ch == 'u') {
          
            if (freq[ch]++ == 0) {
                cnt++;
            }

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

            // If all vowels are present, update result
            if (cnt == 5) {
                ans += (1 + pref);
            }
        } else {
          
            // Reset for non-vowel characters
            cnt = 0;
            pref = 0;
            freq.clear();
            j = i + 1;
        }
    }

    return ans;
}

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

    cout << countVowelSubstrings(str);
    return 0;
}
Java
// Java implementation to count substrings that
// contains all vowels using Sliding Window
import java.util.*;

class GfG {

    // Function to count vowel substrings
    public static int countVowelSubstrings(
            String str) {
        Map<Character, Integer> freq = 
            new HashMap<>();
        int n = str.length();
        int ans = 0;

        // Sliding window approach
        for (int i = 0, cnt = 0, j = 0, 
                pref = 0; i < n; i++) {

            char ch = str.charAt(i);

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

                freq.put(ch, freq.getOrDefault(
                    ch, 0) + 1);

                if (freq.get(ch) == 1) {
                    cnt++;
                }

                // Adjust window to avoid duplicates
                while (freq.getOrDefault(
                        str.charAt(j), 0) > 1) {
                    freq.put(str.charAt(j), 
                        freq.get(str.charAt(j)) - 1);
                    pref++;
                    j++;
                }

                // If all vowels are present, update
                // result
                if (cnt == 5) {
                    ans += (1 + pref);
                }
            } else {

                // Reset for non-vowel characters
                cnt = 0;
                pref = 0;
                freq.clear();
                j = i + 1;
            }
        }

        return ans;
    }

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

        System.out.println(countVowelSubstrings(
            str));
    }
}
Python
# Python implementation to count substrings that 
# contain all vowels using Sliding Window

# Function to count vowel substrings
def countVowelSubstrings(str):
    freq = {}
    n = len(str)
    ans = 0

    # Sliding window approach
    i, cnt, j, pref = 0, 0, 0, 0
    while i < n:
        ch = str[i]

        # Check if character is a vowel
        if ch in "aeiou":
            freq[ch] = freq.get(ch, 0) + 1
            if freq[ch] == 1:
                cnt += 1

            # Adjust window to avoid duplicates
            while freq.get(str[j], 0) > 1:
                freq[str[j]] -= 1
                pref += 1
                j += 1

            # If all vowels are present, update result
            if cnt == 5:
                ans += 1 + pref
        else:
          
            # Reset for non-vowel characters
            cnt = 0
            pref = 0
            freq.clear()
            j = i + 1
        i += 1

    return ans


if __name__ == "__main__":
  
    str = "aeoibsddaaeiouudb"
    
    print(countVowelSubstrings(str))
C#
// C# implementation to count substrings that 
// contain all vowels using Sliding Window
using System;
using System.Collections.Generic;

class GfG {
  
    // Function to count vowel substrings
    public static int CountVowelSubstrings(string str) {
        Dictionary<char, int> freq = 
            new Dictionary<char, int>();
        int n = str.Length;
        int ans = 0;

        // Sliding window approach
        for (int i = 0, cnt = 0, j = 0, 
                pref = 0; i < n; i++) {

            char ch = str[i];

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

                if (!freq.ContainsKey(ch)) {
                    freq[ch] = 0;
                }
                freq[ch]++;

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

                // Adjust window to avoid duplicates
                while (freq.ContainsKey(str[j]) && 
                       freq[str[j]] > 1) {
                    freq[str[j]]--;
                    pref++;
                    j++;
                }

                // If all vowels are present, update
                // result
                if (cnt == 5) {
                    ans += (1 + pref);
                }
            } else {

                // Reset for non-vowel characters
                cnt = 0;
                pref = 0;
                freq.Clear();
                j = i + 1;
            }
        }

        return ans;
    }

    public static void Main(string[] args) {
      
        string str = "aeoibsddaaeiouudb";

        Console.WriteLine(CountVowelSubstrings(str));
    }
}
JavaScript
// Javascript implementation to count substrings that 
// contain all vowels using Sliding Window

// Function to count vowel substrings
function countVowelSubstrings(str) {
    let freq = new Map();
    let n = str.length;
    let ans = 0;

    // Sliding window approach
    let i = 0, cnt = 0, j = 0, pref = 0;
    while (i < n) {
        let ch = str[i];

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

            freq.set(ch, (freq.get(ch) || 0) + 1);
            if (freq.get(ch) === 1) {
                cnt++;
            }

            // Adjust window to avoid duplicates
            while ((freq.get(str[j]) || 0) > 1) {
                freq.set(str[j], freq.get(str[j]) - 1);
                pref++;
                j++;
            }

            // If all vowels are present, update result
            if (cnt === 5) {
                ans += 1 + pref;
            }
        } else {
        
            // Reset for non-vowel characters
            cnt = 0;
            pref = 0;
            freq.clear();
            j = i + 1;
        }
        i++;
    }

    return ans;
}

const str = "aeoibsddaaeiouudb";
console.log(countVowelSubstrings(str));

Output
4

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).
 


Similar Reads