Open In App

Count substrings that contain all vowels | SET 2

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
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:
“aaeiouu”, “aeiouu”, “aeiou” and “aaeiou”
Input: str = “aeoisbddiouuaedf” 
Output: 1
Input: str = “aeouisddaaeeiouua” 
Output:
 

 

Approach: The idea is to extract all the maximum length sub-strings that contain only vowels. Now for all these sub-strings separately, we need to find the count of sub-strings that contains all the vowels at least once. This can be done using two-pointer technique
Illustration of how to use the two-pointer technique in this case: 
 

If string = “aeoibsddaaeiouudb” 
The first step is to extract all maximum length sub-strings that contain only vowels which are: 
 

  1. aeoi
  2. aaeiouu

Now, take the first string “aeoi”, it will not be counted because vowel ‘u’ is missing. 
Then, take the second substring i.e. “aaeiouu” 
Length of the string, n = 7 
start = 0 
index = 0 
count = 0 
We will run a loop till all the vowels are present at least once, so we stop at index 5 and start = 0. 
Now our string is “aaeiou” and there are n – i substrings that contain vowels at least once and have string “aaeiou” as their prefix. 
These substrings are: “aaeiou”, “aaeiouu” 
count = count + (n – i) = 7 – 5 = 2 
Now, count = 2
Then, increment start with 1. If substring between [start, index] i.e (1, 5) still contains vowels at least once then add (n – i). 
These substrings are: “aeiou”, “aeiouu” 
count = count + (n – i) = 7 – 5 = 2 
Now, count = 2
Then start = 2, now substring becomes “eiouu”. Then no further count can be added because vowel ‘a’ is missing. 
 

Below is the implementation of the above approach: 
 

C++




// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function that returns true if c is a vowel
bool isVowel(char c)
{
    return (c == 'a' || c == 'e' || c == 'i'
            || c == 'o' || c == 'u');
}
 
// Function to return the count of sub-strings
// that contain every vowel at least
// once and no consonant
int countSubstringsUtil(string s)
{
    int count = 0;
 
    // Map is used to store count of each vowel
    map<char, int> mp;
 
    int n = s.length();
 
    // Start index is set to 0 initially
    int start = 0;
 
    for (int i = 0; i < n; i++) {
        mp[s[i]]++;
 
        // If substring till now have all vowels
        // atleast once increment start index until
        // there are all vowels present between
        // (start, i) and add n - i each time
        while (mp['a'] > 0 && mp['e'] > 0
               && mp['i'] > 0 && mp['o'] > 0
               && mp['u'] > 0) {
            count += n - i;
            mp[s[start]]--;
            start++;
        }
    }
 
    return count;
}
 
// Function to extract all maximum length
// sub-strings in s that contain only vowels
// and then calls the countSubstringsUtil() to find
// the count of valid sub-strings in that string
int countSubstrings(string s)
{
    int count = 0;
    string temp = "";
 
    for (int i = 0; i < s.length(); i++) {
 
        // If current character is a vowel then
        // append it to the temp string
        if (isVowel(s[i])) {
            temp += s[i];
        }
 
        // The sub-string containing all vowels ends here
        else {
 
            // If there was a valid sub-string
            if (temp.length() > 0)
                count += countSubstringsUtil(temp);
 
            // Reset temp string
            temp = "";
        }
    }
 
    // For the last valid sub-string
    if (temp.length() > 0)
        count += countSubstringsUtil(temp);
 
    return count;
}
 
// Driver code
int main()
{
    string s = "aeouisddaaeeiouua";
 
    cout << countSubstrings(s) << endl;
 
    return 0;
}


Java




// Java implementation of the approach
import java.util.*;
 
class GFG
{
 
// Function that returns true if c is a vowel
static boolean isVowel(char c)
{
    return (c == 'a' || c == 'e' ||
            c == 'i' || c == 'o' || c == 'u');
}
 
// Function to return the count of sub-strings
// that contain every vowel at least
// once and no consonant
static int countSubstringsUtil(char []s)
{
    int count = 0;
 
    // Map is used to store count of each vowel
    Map<Character, Integer> mp = new HashMap<>();
 
    int n = s.length;
 
    // Start index is set to 0 initially
    int start = 0;
 
    for (int i = 0; i < n; i++)
    {
        if(mp.containsKey(s[i]))
        {
            mp.put(s[i], mp.get(s[i]) + 1);
        }
        else
        {
            mp.put(s[i], 1);
        }
 
        // If substring till now have all vowels
        // atleast once increment start index until
        // there are all vowels present between
        // (start, i) and add n - i each time
        while (mp.containsKey('a') && mp.containsKey('e') &&
               mp.containsKey('i') && mp.containsKey('o') &&
               mp.containsKey('u') && mp.get('a') > 0 &&
               mp.get('e') > 0 && mp.get('i') > 0 &&
               mp.get('o') > 0 && mp.get('u') > 0)
        {
            count += n - i;
            mp.put(s[start], mp.get(s[start]) - 1);
 
            start++;
        }
    }
    return count;
}
 
// Function to extract all maximum length
// sub-strings in s that contain only vowels
// and then calls the countSubstringsUtil() to find
// the count of valid sub-strings in that string
static int countSubstrings(String s)
{
    int count = 0;
    String temp = "";
 
    for (int i = 0; i < s.length(); i++)
    {
 
        // If current character is a vowel then
        // append it to the temp string
        if (isVowel(s.charAt(i)))
        {
            temp += s.charAt(i);
        }
 
        // The sub-string containing all vowels ends here
        else
        {
 
            // If there was a valid sub-string
            if (temp.length() > 0)
                count += countSubstringsUtil(temp.toCharArray());
 
            // Reset temp string
            temp = "";
        }
    }
 
    // For the last valid sub-string
    if (temp.length() > 0)
        count += countSubstringsUtil(temp.toCharArray());
 
    return count;
}
 
// Driver code
public static void main(String[] args)
{
    String s = "aeouisddaaeeiouua";
 
    System.out.println(countSubstrings(s));
}
}
 
// This code is contributed by Princi Singh


Python3




# Python3 implementation of the approach
 
# Function that returns true if c is a vowel
def isVowel(c) :
 
    return (c == 'a' or c == 'e' or c == 'i'
            or c == 'o' or c == 'u');
 
 
# Function to return the count of sub-strings
# that contain every vowel at least
# once and no consonant
def countSubstringsUtil(s) :
 
    count = 0;
 
    # Map is used to store count of each vowel
    mp = dict.fromkeys(s,0);
 
    n = len(s);
 
    # Start index is set to 0 initially
    start = 0;
 
    for i in range(n) :
        mp[s[i]] += 1;
 
        # If substring till now have all vowels
        # atleast once increment start index until
        # there are all vowels present between
        # (start, i) and add n - i each time
        while (mp['a'] > 0 and mp['e'] > 0
            and mp['i'] > 0 and mp['o'] > 0
            and mp['u'] > 0) :
            count += n - i;
            mp[s[start]] -= 1;
            start += 1;
 
    return count;
 
# Function to extract all maximum length
# sub-strings in s that contain only vowels
# and then calls the countSubstringsUtil() to find
# the count of valid sub-strings in that string
def countSubstrings(s) :
 
    count = 0;
    temp = "";
 
    for i in range(len(s)) :
 
        # If current character is a vowel then
        # append it to the temp string
        if (isVowel(s[i])) :
            temp += s[i];
 
        # The sub-string containing all vowels ends here
        else :
 
            # If there was a valid sub-string
            if (len(temp) > 0) :
                count += countSubstringsUtil(temp);
 
            # Reset temp string
            temp = "";
 
    # For the last valid sub-string
    if (len(temp) > 0) :
        count += countSubstringsUtil(temp);
 
    return count;
 
# Driver code
if __name__ == "__main__" :
 
    s = "aeouisddaaeeiouua";
 
    print(countSubstrings(s));
 
# This code is contributed by AnkitRai01


C#




// C# implementation of the approach
using System;
using System.Collections.Generic;
 
class GFG
{
 
// Function that returns true if c is a vowel
static bool isVowel(char c)
{
    return (c == 'a' || c == 'e' ||
            c == 'i' || c == 'o' || c == 'u');
}
 
// Function to return the count of sub-strings
// that contain every vowel at least
// once and no consonant
static int countSubstringsUtil(char []s)
{
    int count = 0;
 
    // Map is used to store count of each vowel
    Dictionary<char,
               int> mp = new Dictionary<char,
                                        int>();
 
    int n = s.Length;
 
    // Start index is set to 0 initially
    int start = 0;
 
    for (int i = 0; i < n; i++)
    {
        if(mp.ContainsKey(s[i]))
        {
            mp[s[i]] = mp[s[i]] + 1;
        }
        else
        {
            mp.Add(s[i], 1);
        }
 
        // If substring till now have all vowels
        // atleast once increment start index until
        // there are all vowels present between
        // (start, i) and add n - i each time
        while (mp.ContainsKey('a') && mp.ContainsKey('e') &&
               mp.ContainsKey('i') && mp.ContainsKey('o') &&
               mp.ContainsKey('u') && mp['a'] > 0 &&
               mp['e'] > 0 && mp['i'] > 0 &&
               mp['o'] > 0 && mp['u'] > 0)
        {
            count += n - i;
            if(mp.ContainsKey(s[start]))
                mp[s[start]] = mp[s[start]] - 1;
 
            start++;
        }
    }
    return count;
}
 
// Function to extract all maximum length
// sub-strings in s that contain only vowels
// and then calls the countSubstringsUtil() to find
// the count of valid sub-strings in that string
static int countSubstrings(String s)
{
    int count = 0;
    String temp = "";
 
    for (int i = 0; i < s.Length; i++)
    {
 
        // If current character is a vowel then
        // append it to the temp string
        if (isVowel(s[i]))
        {
            temp += s[i];
        }
 
        // The sub-string containing
        // all vowels ends here
        else
        {
 
            // If there was a valid sub-string
            if (temp.Length > 0)
                count += countSubstringsUtil(temp.ToCharArray());
 
            // Reset temp string
            temp = "";
        }
    }
 
    // For the last valid sub-string
    if (temp.Length > 0)
        count += countSubstringsUtil(temp.ToCharArray());
 
    return count;
}
 
// Driver code
public static void Main(String[] args)
{
    String s = "aeouisddaaeeiouua";
 
    Console.WriteLine(countSubstrings(s));
}
}
 
// This code is contributed by Princi Singh


Javascript




<script>
// JavaScript implementation of the approach
 
// Function that returns true if c is a vowel
function isVowel( c)
{
    return (c == 'a' || c == 'e' || c == 'i'
            || c == 'o' || c == 'u');
}
 
// Function to return the count of sub-strings
// that contain every vowel at least
// once and no consonant
function countSubstringsUtil( s)
{
    var count = 0;
 
    // Map is used to store count of each vowel
    var mp = {};
 
    var n = s.length;
  
 
    // Start index is set to 0 initially
    var start = 0;
 
    for (let i = 0; i < n; i++) {
        if(mp[s[i]]){
           mp[s[i]]++;
        }
        else
            mp[s[i]] = 1;
         
        
        // If substring till now have all vowels
        // atleast once increment start index until
        // there are all vowels present between
        // (start, i) and add n - i each time
       
        while (mp['a'] > 0 && mp['e'] > 0
               && mp['i'] > 0 && mp['o'] > 0
               && mp['u'] > 0) {
            count += n - i;
            mp[s[start]]--;
            start++;
        }
    }
   
    return count;
}
 
// Function to extract all maximum length
// sub-strings in s that contain only vowels
// and then calls the countSubstringsUtil() to find
// the count of valid sub-strings in that string
function countSubstrings( s)
{
    var count = 0;
    var temp = "";
 
    for (let i = 0; i < s.length; i++) {
 
        // If current character is a vowel then
        // append it to the temp string
        if (isVowel(s[i])) {
            temp += s[i];
        }
 
        // The sub-string containing all vowels ends here
        else {
 
            // If there was a valid sub-string
            if (temp.length > 0)
                count += countSubstringsUtil(temp);
 
            // Reset temp string
            temp = "";
        }
    }
 
    // For the last valid sub-string
    if (temp.length > 0)
        count += countSubstringsUtil(temp);
 
    return count;
}
 
// Driver code
 
var s = "aeouisddaaeeiouua";
console.log( countSubstrings(s));
 
// This code is contributed by ukasp.   
 
</script>


Output

9

Time Complexity: O(N^2)

Auxiliary Space: O(N), since Hashmap is used and memory is allocated in each iteration.

Optimized approach using Sliding Window -:

The idea is to keep track of all the vowels and count the substrings containing all vowels using a sliding window approach.

Intution :
Maintains a count of vowels in the current substring and a temporary array to keep track of the count of each vowel in the substring.
When the count of all the vowels in the substring is 5, then count all the substring in the substring forming from i to j.
If the current character is not a vowel, it resets the start pointer and the count and the array.
Finally, it returns the answer which is the count of all substrings that contain all the vowels.
Algorithm :
1. Initialize variables i, j, count, and ans to 0, and create an integer array arr of size 26.
2. Iterate through the string using variable j.
3. If the current character ch is a vowel, increment the count of that vowel in the arr array, and if the count of that vowel is 1 (i.e., it is the first occurrence), increment the count variable.
4. If count is equal to 5 (i.e., all vowels have been seen at least once), then initialize a new integer array temp to keep track of the counts of vowels in the current substring, and loop through the characters from index i to j.
5. For each character, decrement the count of that vowel in the temp array, and if the count becomes 0, decrement the count variable.
6. Increment the ans variable for each iteration of the loop in step 5, because each substring from i to j containing all vowels will be counted.
7. Once count becomes less than 5 (i.e., the current substring no longer contains all vowels), set i to j+1, set count to 0, and create a new arr array.
8. Continue iterating through the string until the end is reached, and then return the ans variable.

Pseudocode : 

function countVowelSubstrings(word):
n = length of word
arr = array of 26 zeros
i = 0
j = 0
count = 0
ans = 0

while j < n do:
ch = character at index j in word
if checkVowel(ch) then:
if arr[ch - 'a'] == 0 then:
count = count + 1
arr[ch - 'a'] = arr[ch - 'a'] + 1

if count == 5 then:
val = i
temp = array of 26 zeros
temp['a' - 'a'] = arr['a' - 'a']
temp['e' - 'a'] = arr['e' - 'a']
temp['i' - 'a'] = arr['i' - 'a']
temp['o' - 'a'] = arr['o' - 'a']
temp['u' - 'a'] = arr['u' - 'a']

while count == 5 do:
ans = ans + 1
c = character at index val in word
temp = temp - 1
if temp == 0 then:
count = count - 1
val = val + 1

count = 5
end if
else:
i = j + 1
count = 0
arr = array of 26 zeros
end if

j = j + 1
end while

return ans
end function
function checkVowel(ch):
if ch == 'a' or ch == 'e' or ch == 'i' or ch == 'o' or ch == 'u' then:
return true
else:
return false
end if
end function

C++




#include <bits/stdc++.h>
using namespace std;
 
// function to check that a character is a vowel or not
bool checkVowel(char ch) {
    if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {
        return true;
    }
    return false;
}
 
// function will return the number of count of vowel substrings
int countVowelSubstrings(string word) {
    int n = word.length();
 
    int arr[26];
      // initializing the array with 0
    memset(arr, 0, sizeof(arr));
    int i = 0;
    int j = 0;
    int count = 0;
    int ans = 0;
    while (j < n) {
        char ch = word[j];
        if (checkVowel(ch)) {
            if (arr[ch - 'a'] == 0) {
                count++;
            }
            arr[ch - 'a']++;
 
            if (count == 5) {
                int val = i;
                int temp[26];
                memcpy(temp, arr, sizeof(temp));
 
                while (count == 5) {
                    ans++;
 
                    char c = word[val];
                    temp--;
                    if (temp == 0) {
                        count--;
                    }
                    val++;
                }
                count = 5;
            }
        } else {
            i = j + 1;
            count = 0;
            memset(arr, 0, sizeof(arr));
        }
 
        j++;
    }
 
    return ans;
}
 
// driver program to test above functions
int main() {
    string s = "aeouisddaaeeiouua";
 
    cout << countVowelSubstrings(s);
}


Java




/*package whatever //do not write package name here */
 
import java.io.*;
 
class GFG {
      public static int countVowelSubstrings(String word) {
        int n = word.length();
 
        int []arr = new int[26];
        int i = 0;
        int j = 0;
        int count = 0;
        int ans = 0;
        while(j < n){
            char ch = word.charAt(j);
            if(checkVowel(ch)){
                if(arr[ch - 'a'] == 0){
                    count++;
                }
                arr[ch - 'a']++;
 
                if(count == 5){
                    int val = i;
                    int []temp = new int[26];
                    temp['a' - 'a'] = arr['a' - 'a'];
                    temp['e' - 'a'] = arr['e' - 'a'];
                    temp['i' - 'a'] = arr['i' - 'a'];
                    temp['o' - 'a'] = arr['o' - 'a'];
                    temp['u' - 'a'] = arr['u' - 'a'];
 
                    while(count == 5){
                        ans++;
 
                        char c = word.charAt(val);
                        temp--;
                        if(temp == 0){
                            count--;
                        }
                        val++;
                    }
                    count = 5;
                }
            }
            else{
                i = j+1;
                count = 0;
                arr = new int[26];
            }
 
            j++;
        }
 
        return ans;
    }
    public static boolean checkVowel(char ch){
        if(ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u'){
            return  true;
        }
        return false;
    }
    public static void main (String[] args) {
        String s = "aeouisddaaeeiouua";
  
        System.out.println(countVowelSubstrings(s));
    }
}
 
// This code is contributed by vishalkumarsahu04


Python




# Function to check if a character is a vowel or not
def check_vowel(ch):
    return ch in ['a', 'e', 'i', 'o', 'u']
 
# Function to count vowel substrings
def count_vowel_substrings(word):
    n = len(word)
     
    arr = [0] * 26  # Initializing the array with 0
    i = j = count = ans = 0
     
    while j < n:
        ch = word[j]
         
        if check_vowel(ch):
            if arr[ord(ch) - ord('a')] == 0:
                count += 1
            arr[ord(ch) - ord('a')] += 1
 
            if count == 5:
                val = i
                temp = arr[:]
                 
                while count == 5:
                    ans += 1
                     
                    c = word[val]
                    temp[ord(c) - ord('a')] -= 1
                    if temp[ord(c) - ord('a')] == 0:
                        count -= 1
                    val += 1
                count = 5
        else:
            i = j + 1
            count = 0
            arr = [0] * 26
 
        j += 1
     
    return ans
 
# Driver program to test the above functions
if __name__ == "__main__":
    s = "aeouisddaaeeiouua"
    print(count_vowel_substrings(s))


C#




using System;
 
class Program {
    // function to check that a character is a vowel or not
    static bool CheckVowel(char ch)
    {
        if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o'
            || ch == 'u') {
            return true;
        }
        return false;
    }
 
    // function will return the number of count of vowel
    // substrings
    static int CountVowelSubstrings(string word)
    {
        int n = word.Length;
 
        int[] arr = new int[26];
        // initializing the array with 0
        Array.Fill(arr, 0);
        int i = 0;
        int j = 0;
        int count = 0;
        int ans = 0;
        while (j < n) {
            char ch = word[j];
            if (CheckVowel(ch)) {
                if (arr[ch - 'a'] == 0) {
                    count++;
                }
                arr[ch - 'a']++;
 
                if (count == 5) {
                    int val = i;
                    int[] temp = new int[26];
                    Array.Copy(arr, temp, arr.Length);
 
                    while (count == 5) {
                        ans++;
 
                        char c = word[val];
                        temp--;
                        if (temp == 0) {
                            count--;
                        }
                        val++;
                    }
                    count = 5;
                }
            }
            else {
                i = j + 1;
                count = 0;
                Array.Fill(arr, 0);
            }
 
            j++;
        }
 
        return ans;
    }
 
    // driver program to test above functions
    static void Main(string[] args)
    {
        string s = "aeouisddaaeeiouua";
 
        Console.WriteLine(CountVowelSubstrings(s));
    }
}
// This code is contributed by user_dtewbxkn77n


Javascript




// Function to check if a character is a vowel or not
function checkVowel(ch) {
    return ch === 'a' || ch === 'e' || ch === 'i' || ch === 'o' || ch === 'u';
}
 
// Function to count vowel substrings
function countVowelSubstrings(word) {
    const n = word.length;
 
    const arr = Array(26).fill(0);
    let i = 0;
    let j = 0;
    let count = 0;
    let ans = 0;
 
    while (j < n) {
        const ch = word[j];
 
        if (checkVowel(ch)) {
            if (arr[ch.charCodeAt(0) - 'a'.charCodeAt(0)] === 0) {
                count++;
            }
            arr[ch.charCodeAt(0) - 'a'.charCodeAt(0)]++;
 
            if (count === 5) {
                let val = i;
                const temp = [...arr];
 
                while (count === 5) {
                    ans++;
 
                    const c = word[val];
                    temp--;
 
                    if (temp === 0) {
                        count--;
                    }
                    val++;
                }
                count = 5;
            }
        } else {
            i = j + 1;
            count = 0;
            arr.fill(0);
        }
 
        j++;
    }
 
    return ans;
}
 
// Driver program to test the function
function main() {
    const s = "aeouisddaaeeiouua";
    console.log(countVowelSubstrings(s));
}
 
// Run the main function
main();


Output

9

Time Complexity — O(N)

Auxiliary Space — O(26) i.e O(1)
 



Last Updated : 16 Oct, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads