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: 4
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: 9
Explanation: There are 9 distinct substrings containing all vowels in order in the given string.
Table of Content
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++ 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 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 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# 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 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++ 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 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 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# 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 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).