Maximum Number of Vowels in a Substring of Given Length

Problem

Given a string s and an integer k, return the maximum number of vowel letters in any substring of s with length k.

  • 1 ≤ s.length ≤ 10⁵
  • s consists of lowercase English letters.
  • 1 ≤ k ≤ s.length

Example

Input: s = "abciiidef", k = 3
Output: 3

The substring "iii" contains 3 vowels, which is the maximum possible for any substring of length 3. The algorithm uses a sliding window of size k to track the count of vowels in the current window. Starting with the first k characters, it counts vowels and then slides the window one character at a time, updating the count by removing the leftmost character and adding the new rightmost character. The maximum count encountered during this process is returned.

Approach

Straightforward Solution

A brute-force approach would check every substring of length k, counting vowels each time, resulting in O(n*k) time complexity, which is inefficient for large strings.

Core Observation

The problem requires finding the maximum number of vowels in any substring of fixed length k. This is a classic scenario for a sliding window approach, where the window size is fixed and the goal is to efficiently update the count as the window moves.

Path to Optimal

Recognizing that the window size is fixed allows the use of a sliding window that moves one character at a time. Instead of recounting vowels from scratch for each window, the algorithm updates the count by subtracting the contribution of the character leaving the window and adding the contribution of the new character entering. This reduces the time complexity to O(n).

Optimal Approach

Use a sliding window of size k. Initialize pointers l and r to define the window boundaries. Maintain a running count of vowels in the current window. For each step, add the vowel contribution of the new character at r, and if the window size exceeds k, subtract the vowel contribution of the character at l and move l forward. Track the maximum vowel count seen during the process and return it at the end.

Time

O(n)

Each character is visited at most twice: once when entering the window and once when leaving it, resulting in a linear time complexity.

Space

O(1)

Only a fixed-size set for vowels and a few integer variables are used, independent of input size.

Pattern Spotlight

Sliding Window (Fixed-Size Window)

When asked to find a maximum or minimum value over all substrings or subarrays of fixed length, use a sliding window that updates state incrementally by adding the new element and removing the old, avoiding recomputation.

Solution

1class Solution:
2 def maxVowels(self, s: str, k: int) -> int:
3 vowels = set("aeiou")
4 l = 0
5 cur = 0
6 ans = 0
7
8 for r in range(len(s)):
9 cur += s[r] in vowels
10 if r - l + 1 > k:
11 cur -= s[l] in vowels
12 l += 1
13 if r - l + 1 == k:
14 ans = max(ans, cur)
15
16 return ans

Step-by-Step Solution

1

Initialize Vowel Set and Sliding Window State

3vowels = set("aeiou")
4l = 0
5cur = 0
6ans = 0

Objective

To prepare the data structures and variables needed to track vowels and window boundaries.

Key Insight

Using a set for vowels allows O(1) membership checks, which is critical for efficient counting. Initializing the left pointer and counters sets the stage for the sliding window traversal, ensuring the algorithm can update counts incrementally as the window moves.

Interview Quick-Check

Core Logic

The vowel set enables constant-time checks to determine if a character is a vowel, which is essential for efficient counting.

State & Boundaries

Initialize the left pointer `l` at 0 and counters `cur` and `ans` at 0 to track the current vowel count and the maximum found.

Common Pitfalls & Bugs

Forgetting to initialize the maximum answer `ans` to zero can lead to incorrect results if all substrings have zero vowels.

2

Slide Window Across String and Update Vowel Counts

8for r in range(len(s)):
9 cur += s[r] in vowels
10 if r - l + 1 > k:
11 cur -= s[l] in vowels
12 l += 1
13 if r - l + 1 == k:
14 ans = max(ans, cur)

Objective

To iterate through the string with a right pointer, updating the vowel count for the current window and adjusting the left pointer to maintain window size k.

Key Insight

Incrementally updating the vowel count by adding the new character's contribution and subtracting the old character's contribution when the window exceeds size k avoids recomputing counts from scratch. This incremental update is the core efficiency gain of the sliding window technique.

Interview Quick-Check

Core Logic

The algorithm adds 1 to `cur` if the new character is a vowel, and subtracts 1 if the character leaving the window is a vowel, maintaining an accurate count of vowels in the current window.

State & Boundaries

The window size is controlled by checking if `r - l + 1 > k` and moving the left pointer accordingly to keep the window size fixed.

Common Pitfalls & Bugs

Failing to update the left pointer and vowel count when the window size exceeds k leads to incorrect window sizes and counts.

Complexity

This approach ensures each character is processed at most twice, resulting in O(n) time complexity.

3

Return the Maximum Vowel Count Found

16return ans

Objective

To output the maximum number of vowels found in any substring of length k after processing the entire string.

Key Insight

Returning the tracked maximum ensures the algorithm outputs the correct result after considering all valid windows. This final step completes the sliding window traversal.

Interview Quick-Check

Core Logic

Returning `ans` provides the maximum vowel count found across all substrings of length k.

Line Analysis

This solution has 2 Critical lines interviewers watch for.

Line 9 Critical
cur += s[r] in vowels

Increment the current vowel count if the new character is a vowel.

Incrementing the count based on the new character's vowel status is the key incremental update that avoids recomputing the entire window's vowel count.

Line 11 Critical
cur -= s[l] in vowels

Decrement the current vowel count if the character leaving the window is a vowel.

Subtracting the vowel contribution of the character leaving the window is critical to maintain correctness while sliding the window efficiently.

Line 3 Core
vowels = set("aeiou")

Create a set containing all vowel characters for O(1) membership checks.

Using a set for vowels allows the algorithm to quickly determine if a character is a vowel, which is essential for efficient counting during the sliding window traversal.

Line 14 Core
ans = max(ans, cur)

Update the maximum vowel count if the current count is greater.

Tracking the maximum count ensures the algorithm returns the best possible answer after examining all valid windows.

Line 5 Core
cur = 0

Initialize the current vowel count within the window to 0.

Tracking the current number of vowels in the window allows incremental updates as the window slides, avoiding recomputation.

Line 6 Core
ans = 0

Initialize the answer to store the maximum vowel count found so far.

This variable accumulates the best result seen during the traversal, ensuring the final output is correct.

Line 10 Core
if r - l + 1 > k:

Check if the window size exceeds k.

This condition ensures the window size remains fixed at k by triggering the removal of the leftmost character when necessary.

Line 12 Core
l += 1

Move the left pointer forward to shrink the window back to size k.

Advancing the left pointer maintains the fixed window size and ensures the window slides forward correctly.

Line 13 Core
if r - l + 1 == k:

Check if the current window size equals k.

Only windows of size exactly k are valid candidates for the answer, so this condition gates the update of the maximum vowel count.

Line 16 Core
return ans

Return the maximum vowel count found in any substring of length k.

This final return outputs the result of the sliding window traversal, completing the algorithm.

Line 4 Standard
l = 0

Initialize the left pointer of the sliding window to 0.

The left pointer marks the start of the current window and is essential for maintaining the fixed window size k as the right pointer advances.

Line 8 Standard
for r in range(len(s)):

Iterate over the string with the right pointer to expand the sliding window.

The right pointer moves through the string, adding new characters to the window and enabling the algorithm to examine every substring of length k.

Test Your Understanding

Why does updating the vowel count incrementally as the window slides guarantee correctness and efficiency?

Because the window size is fixed, the difference between consecutive windows is exactly one character entering and one leaving. Updating the count by adding the new character's vowel contribution and subtracting the old one's avoids recounting the entire window, ensuring O(n) time and correctness.

Related Problems

Sliding Window pattern

Don't just read it. Drill it.

Reconstruct Maximum Number of Vowels in a Substring of Given Length from memory until it sticks. AlgoDrill blanks out key lines and makes you fill them back in, step by step.

Unlock the Maximum Number of Vowels in a Substring of Given Length drill

or drill a free problem