Problem Statement in English
You’re given a string word and an integer k. You need to count the number of substrings of word that contain all 5 vowels (a, e, i, o, u) and exactly k consonants.
Approach
The problem with going sliding window on this is that as we move the right pointer to the right the number of consonants can increase as we move the left pointer to the right, while the vowels only increase.
So we approach the problem from an angle that both the number of vowels and consonants can increase. We look for atleast k consonants and all 5 vowels, and then we look for at least k + 1 consonants and all 5 vowels. The difference between the two will give us the number of substrings with exactly k consonants. Neat trick.
And we’re done!
Solution in Python
class Solution:
def countOfSubstrings(self, word: str, k: int) -> int:
# Helper function: Counts substrings with ALL 5 vowels and >= k consonants
def atLeastK(k: int) -> int:
vowels_count = {}
consonants = 0
left = 0
res = 0
for right in range(len(word)):
char = word[right]
# 1. Add the right character to our window
if char in "aeiou":
vowels_count[char] = vowels_count.get(char, 0) + 1
else:
consonants += 1
# 2. While the window is valid, shrink it from the left
while len(vowels_count) == 5 and consonants >= k:
left_char = word[left]
if left_char in "aeiou":
vowels_count[left_char] -= 1
if vowels_count[left_char] == 0:
del vowels_count[left_char]
else:
consonants -= 1
left += 1
# 3. Add the number of valid starting positions to our result
res += left
return res
# The magic formula
return atLeastK(k) - atLeastK(k + 1)
Complexity
Time: $O(n)$
Since we traverse the string a few times with the two-pointer technique.Space: $O(1)$
Since we only store counts of vowels and consonants, which is constant space.
Mistakes I Made
I had to look this one up :(
And we are done.