Data Structures and Algorithms

Finding the Maximum Number of Vowels in a Substring

6 days, 4 hours 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

Problem-solving techniques in DSA

Problem-Solving in Data Structures and Algorithms   Here's an all-inclusive guid… Read More

1 week, 2 days ago . 216 views