Lexicographically smallest K-length substring containing maximum number of vowels

Given a string str containing only lowercase English alphabets and an integer K, the task is to find a K length substring which contains the maximum number of vowels (i.e. ‘a’, ‘e’, ‘i’, ‘o’, ‘u’). If there are multiple such substrings, return the substring which is lexicographically smallest.

Examples:

Input: str = “geeksforgeeks”, K = 4
Output: eeks
Explanation:
The substrings with maximum count of vowels are “geek”, “eeks” which contains 2 vowels. But “eeks” is lexicographically smallest.

Input: str = “ceebbaceeffo”, K = 3
Output: ace
Explanation:
Lexicographically substrings with maximum count of vowels are “ace”.

Naive Approach:
To solve the problem mentioned above we have to generate all the substrings of length K and store the lexicographically smallest of all such substrings which contains the maximum number of vowels.
Time Complexity: O(N2)



Efficient Approach:
The above mentioned procedure can be optimized by creating a prefix sum array pref[] of vowels where the ith index contains the count of vowels from 0 to the ith index. The count of vowels for any substring str[l : r] can be given by pref[r]-pref[l-1]. Then, find the lexicographically smallest substring with the maximum count of vowels.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find
// lexicographically smallest
// K-length substring containing
// maximum number of vowels
  
#include <bits/stdc++.h>
using namespace std;
  
// Function that prints the
// lexicographically smallest
// K-length substring containing
// maximum number of vowels
string maxVowelSubString(
    string str, int K)
{
    // Store the length of the string
    int N = str.length();
  
    // Initialize a prefix sum array
    int pref[N];
  
    // Loop through the string to
    // create the prefix sum array
    for (int i = 0; i < N; i++) {
  
        // Store 1 at the index
        // if it is a vowel
        if (str[i] == 'a'
            or str[i] == 'e'
            or str[i] == 'i'
            or str[i] == 'o'
            or str[i] == 'u')
            pref[i] = 1;
  
        // Otherwise, store 0
        else
            pref[i] = 0;
  
        // Process the prefix array
        if (i)
            pref[i] += pref[i - 1];
    }
  
    // Initialize the variable to store
    // maximum count of vowels
    int maxCount = pref[K - 1];
  
    // Initialize the variable
    // to store substring
    // with maximum count of vowels
    string res = str.substr(0, K);
  
    // Loop through the prefix array
    for (int i = K; i < N; i++) {
  
        // Store the current
        // count of vowels
        int currCount
            = pref[i]
              - pref[i - K];
  
        // Update the result if current count
        // is greater than maximum count
        if (currCount > maxCount) {
  
            maxCount = currCount;
            res = str.substr(i - K + 1, K);
        }
  
        // Update lexicographically smallest
        // substring if the current count
        // is equal to the maximum count
        else if (currCount == maxCount) {
  
            string temp
                = str.substr(
                    i - K + 1, K);
  
            if (temp < res)
                res = temp;
        }
    }
  
    // Return the result
    return res;
}
  
// Driver Program
int main()
{
    string str = "ceebbaceeffo";
    int K = 3;
  
    cout << maxVowelSubString(str, K);
  
    return 0;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to find
# lexicographically smallest
# K-length substring containing
# maximum number of vowels
  
# Function that prints the
# lexicographically smallest
# K-length substring containing
# maximum number of vowels
def maxVowelSubString(str1, K):
      
    # Store the length of the string
    N = len(str1)
  
    # Initialize a prefix sum array
    pref = [0 for i in range(N)]
  
    # Loop through the string to
    # create the prefix sum array
    for i in range(N):
          
        # Store 1 at the index
        # if it is a vowel
        if (str1[i] == 'a' or 
            str1[i] == 'e' or 
            str1[i] == 'i' or
            str1[i] == 'o' or 
            str1[i] == 'u'):
            pref[i] = 1
  
        # Otherwise, store 0
        else:
            pref[i] = 0
  
        # Process the prefix array
        if (i):
            pref[i] += pref[i - 1]
  
    # Initialize the variable to 
    # store maximum count of vowels
    maxCount = pref[K - 1]
  
    # Initialize the variable
    # to store substring with 
    # maximum count of vowels
    res = str1[0:K]
  
    # Loop through the prefix array
    for i in range(K, N):
          
        # Store the current
        # count of vowels
        currCount = pref[i] - pref[i - K]
  
        # Update the result if current count
        # is greater than maximum count
        if (currCount > maxCount):
            maxCount = currCount
            res = str1[i - K + 1 : i + 1]
  
        # Update lexicographically smallest
        # substring if the current count
        # is equal to the maximum count
        elif (currCount == maxCount):
            temp = str1[i - K + 1 : i + 1]
  
            if (temp < res):
                res = temp
  
    # Return the result
    return res
  
# Driver code
if __name__ == '__main__':
      
    str1 = "ceebbaceeffo"
    K = 3
  
    print(maxVowelSubString(str1, K))
  
# This code is contributed by Surendra_Gangwar

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find
// lexicographically smallest
// K-length substring containing
// maximum number of vowels
using System;
class GFG{
  
// Function that prints the
// lexicographically smallest
// K-length substring containing
// maximum number of vowels
static string maxVowelSubString(string str,
                                int K)
{
    // Store the length of the string
    int N = str.Length;
  
    // Initialize a prefix sum array
    int []pref = new int[N];
  
    // Loop through the string to
    // create the prefix sum array
    for (int i = 0; i < N; i++) 
    {
  
        // Store 1 at the index
        // if it is a vowel
        if (str[i] == 'a' ||
            str[i] == 'e' || 
            str[i] == 'i' || 
            str[i] == 'o' || 
            str[i] == 'u')
            pref[i] = 1;
  
        // Otherwise, store 0
        else
            pref[i] = 0;
  
        // Process the prefix array
        if (i != 0)
            pref[i] += pref[i - 1];
    }
  
    // Initialize the variable to store
    // maximum count of vowels
    int maxCount = pref[K - 1];
  
    // Initialize the variable
    // to store substring
    // with maximum count of vowels
    string res = str.Substring(0, K);
  
    // Loop through the prefix array
    for (int i = K; i < N; i++)
    {
  
        // Store the current
        // count of vowels
        int currCount = pref[i] - 
                        pref[i - K];
  
        // Update the result if current count
        // is greater than maximum count
        if (currCount > maxCount) 
        {
            maxCount = currCount;
            res = str.Substring(i - K + 1, K);
        }
  
        // Update lexicographically smallest
        // substring if the current count
        // is equal to the maximum count
        else if (currCount == maxCount)
        {
            string temp = str.Substring(i - K + 1, K);
  
            if (string.Compare(temp, res) == -1)
                res = temp;
        }
    }
  
    // Return the result
    return res;
}
  
// Driver Code
public static void Main()
{
    string str = "ceebbaceeffo";
    int K = 3;
  
    Console.Write(maxVowelSubString(str, K));
}
}
  
// This code is contributed by Code_Mech

chevron_right


Output:

ace

Time Complexity: O(N)

competitive-programming-img




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.