Lexicographically smallest K-length substring containing maximum number of vowels

Given 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


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find
// lexicographically smallest
// K-length substring containing
// maximum number of vowels
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.charAt(i) == 'a' ||
        str.charAt(i) == 'e' ||
        str.charAt(i) == 'i' ||
        str.charAt(i) == 'o' ||
        str.charAt(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,
                          i + 1);
    }
 
    // 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,
                                  i + 1);
 
      if (temp.compareTo(res) < 0)
        res = temp;
    }
  }
 
  // Return the result
  return res;
}
 
// Driver Code
public static void main(String []args)
{
  String str = "ceebbaceeffo";
  int K = 3;
  System.out.print(maxVowelSubString(str, K));
}
}
 
// This code is contributed by Chitranayal

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.