Data Structures and Algorithms

Finding the Maximum Number of Vowels in a Substring

4 weeks ago ; F(visit_count) + Value(1) views
Share this

Finding the Maximum Number of Vowels in a Substring

 

I will help you find the number of vowels in a substring of fixed length. 

This is a common problem in both text processing and algorithm optimization.

As a result, I will show you how to arrive at the efficient solution from the many solutions.

As an experienced software engineer specializing in algorithm optimization, I will walk you through an initial non-optimized approach and then introduce a highly optimized version using the Sliding Window technique.

By the end of this article, you'll understand why an optimized solution is crucial for efficiently handling large-scale text processing.

 

Understanding the Problem

Given a string s and a number k, our goal is to determine the maximum number of vowels in any substring of length k.

 

Substring - continuous sequence of characters in the string.

Example

Input:

s = "bacacbefaobeacfe"

k = 5

Output:

4 # Substring "aobea" contains four vowels.

Solution 1: Brute-force counting (Non-Optimized Approach)

Check all length k's possible substrings in string s while:-

  1. Counting the number of vowels in each
  2. Track the maximum count found
def count_vowels(s):
    """
    Function to count vowels in a string

    Args:
       s(str): input string
    Returns:
       int: count of vowels in a given substring
    """

    count = 0

    for i in ["a", "e", "i", "o", "u"]: # Check for each vowel

        count += s.count(i) # Count occurrences of each vowel in the substring

    return count


def max_vowels(s, k):

    """

    Function to find max vowels in any substring of length k

    Args:
      s(str): string to find substrings in
      k(int): maximum number of vowels in a substring

    """

    max_val = 0

    for i in range(len(s) - k + 1): # Iterate over each possible substring of length k

        substr = s[i:i+k] # Extract substring

        max_val = max(max_val, count_vowels(substr)) # Update max count    

    return max_val


# Test Case
print("Answer:", max_vowels("bacacbefaobeacfe", 5)) # Output: 4

 

Areas of Inefficiency?

Time Complexity: O(n * k)

Each substring of length k is analyzed independently, leading to unnecessary repeated computations.

Performance Issue

For large strings, this approach becomes too slow.

 

Solution 2: Sliding Window Technique (Optimized Approach)

Instead of recalculating the number of vowels in each substring from scratch, we use a sliding window.

  1. Count vowels in the first k characters.
  2. Slide the window one step at a time:
    • Remove the leftmost character's contribution.
    • Add the new rightmost character's contribution.
  3. Keep track of the maximum vowel count encountered.

 

def max_vowels(s, k):

    """

    Finds the maximum number of vowels in any substring of length k.

    Uses the sliding window technique for optimal performance.

    

    Args:

       s(str): Input string

       k(int): Size of the substring window

   Returns:

      Maximum number of vowels in a k-length substring

    """

    vowels = {"a", "e", "i", "o", "u"} # Set lookup is O(1)

    max_count = 0

    current_count = sum(1 for i in s[:k] if i in vowels) # Count vowels in the first k-length window


    max_count = current_count # Initialize max with the first count


    for i in range(k, len(s)):

        # Remove leftmost character from window count

        if s[i - k] in vowels:

            current_count -= 1

        # Add new rightmost character to window count

        if s[i] in vowels:

            current_count += 1

        max_count = max(max_count, current_count) # Update max if needed


    return max_count


# Test Case

print("Answer:", max_vowels("bacacbefaobeacfe", 5)) # Output: 4

 

Why is this Better?

This solution is better because of the time complexity.

Time Complexity: O(n)

Update vowel count in constant time instead of recalculating for each substring.

Space Complexity: O(1)

Keeps memory usage to a minimum - few variables.

Performance Comparison

 Approach                                                                   Time Complexity                                                                 Space Complexity

Brute Force                                                                    O(n * k)                                                                                          O(1)

Sliding Window                                                             O(n)                                                                                                O(1)

 

For large input sizes, the optimized solution is significantly faster.

Next Steps: Where to Go from Here?

Now that you understand how to optimize substring-based problems, you can:

  • Apply the Sliding Window technique to similar problems like longest repeating character replacement.
  • Try modifying this algorithm to support custom vowel sets (e.g., considering y as a vowel in some cases).
  • Optimize further by using bitwise operations for extremely large datasets.

By implementing these optimizations, you can significantly improve your coding efficiency and problem-solving skills.

Become a member
Get the latest news right in your inbox. We never spam!

Read next

How to Check If Two Words Are Anagrams in Python

How to Check if Two Words are Anagrams in Python Clarity and precision are essential in sol… Read More

3 days, 8 hours ago . 256 views