Taro Logo

Maximum Number of Vowels in a Substring of Given Length

Medium
2 months ago

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

Vowel letters in English are 'a', 'e', 'i', 'o', and 'u'.

For example:

  1. If s = "abciiidef", and k = 3, the expected output is 3 because the substring "iii" contains 3 vowel letters.
  2. If s = "aeiou", and k = 2, the expected output is 2 because any substring of length 2 contains 2 vowels.
  3. If s = "leetcode", and k = 3, the expected output is 2 because "lee", "eet" and "ode" contain 2 vowels.
Sample Answer
## Maximum Number of Vowels in a Substring

This problem asks us to find the maximum number of vowel letters within any substring of length `k` in a given string `s`. We need to iterate through the string and count vowels in substrings of length `k`, keeping track of the maximum count encountered.

### Naive Solution (Brute Force)

The simplest approach is to iterate through all possible substrings of length `k` and count the vowels in each substring. This is a straightforward but potentially inefficient method.

```python
def max_vowels_brute_force(s: str, k: int) -> int:
    max_vowel_count = 0
    for i in range(len(s) - k + 1):
        substring = s[i:i+k]
        vowel_count = 0
        for char in substring:
            if char in 'aeiou':
                vowel_count += 1
        max_vowel_count = max(max_vowel_count, vowel_count)
    return max_vowel_count

# Example usage:
s = "abciiidef"
k = 3
print(max_vowels_brute_force(s, k))  # Output: 3

s = "aeiou"
k = 2
print(max_vowels_brute_force(s, k))  # Output: 2

s = "leetcode"
k = 3
print(max_vowels_brute_force(s, k))  # Output: 2

Optimal Solution (Sliding Window)

A more efficient approach is to use the sliding window technique. We can maintain a window of size k and slide it through the string. While sliding, we update the vowel count by adding the new character (if it's a vowel) and subtracting the character that exits the window (if it was a vowel).

def max_vowels_sliding_window(s: str, k: int) -> int:
    vowels = 'aeiou'
    current_vowel_count = 0
    for i in range(k):
        if s[i] in vowels:
            current_vowel_count += 1
    
    max_vowel_count = current_vowel_count
    
    for i in range(k, len(s)):
        if s[i] in vowels:
            current_vowel_count += 1
        if s[i - k] in vowels:
            current_vowel_count -= 1
        max_vowel_count = max(max_vowel_count, current_vowel_count)
    
    return max_vowel_count

# Example usage:
s = "abciiidef"
k = 3
print(max_vowels_sliding_window(s, k))  # Output: 3

s = "aeiou"
k = 2
print(max_vowels_sliding_window(s, k))  # Output: 2

s = "leetcode"
k = 3
print(max_vowels_sliding_window(s, k))  # Output: 2

Big(O) Runtime Analysis

Brute Force:

  • The outer loop iterates n - k + 1 times, where n is the length of the string.
  • The inner loop iterates k times.
  • Therefore, the time complexity is O((n - k + 1) * k), which simplifies to O(n*k) in the worst case (when k is small relative to n).

Sliding Window:

  • The initial loop iterates k times.
  • The subsequent loop iterates n - k times.
  • Each iteration involves constant-time operations.
  • Therefore, the time complexity is O(k + (n - k)), which simplifies to O(n).

Big(O) Space Usage Analysis

Brute Force:

  • The space complexity is O(1) as it uses only a few extra variables.

Sliding Window:

  • The space complexity is O(1) as it uses only a few extra variables to store counts.

Edge Cases

  1. Empty String: If the input string s is empty, we should return 0 as there are no substrings. The code handles this implicitly because the loops won't execute.
  2. k is larger than the string length: If k is greater than the length of s, we should return 0, because there are no substrings of length k. The brute force solution handles this by the loop condition, while the sliding window solution will have the range loop not execute.
  3. String with no vowels: If the string contains no vowels, the function should return 0. Both solutions correctly handle this.
  4. k is 1: If k is 1, we iterate through the string and count the maximum number of vowels, which will be either 0 or 1.
  5. String contains only vowels: If the string consists entirely of vowels, the function should return k.

All of the solutions above will implicitly address these edge cases without the need for additional checks, since they will naturally evaluate to the correct result.