Length of the smallest substring which contains all vowels - GeeksforGeeks

08 Jun, 2021
Given string str consisting of only lowercase English alphabets, the task is to find the substring of the smallest length which contains all the vowels. If no such substring is found, print -1.
Example:  
Input: str = “babeivoucu” Output: 7 Explanation: Smallest substring which contains each vowel atleast once is “abeivou” of length 7.
Input: str = “abcdef” Output: -1 Explanation: No such substring is found. 
Two Pointer Approach:  
Store the frequencies of each vowel and the indices at which the vowels are present.
If all the vowels are not present, straightaway print -1.
Take two pointers i and j at the first and last indices containing a vowel.
If the frequencies of vowel at ith and jth index exceed 1, decrease the count of that vowel and shift i and j to the right and left respectively to the next index containing a vowel.
If the frequencies of vowel at ith or jth index is equal to 1, set flag1 or flag2 respectively and continue.
Once both flag1 and flag2 are set, the length of the substring cannot be further minimized. The distance between the current indices pointed by the two pointers denotes the result.
The below code is the implementation of the above approach: 
C++
Java
Python3
C#
Javascript
// C++ Program to find the// length of the smallest// substring of which// contains all vowels #include <bits/stdc++.h>using namespace std; int findMinLength(string s){    int n = s.size();     // Map to store the    // frequency of vowels    map<char, int> counts;     // Store the indices    // which contains    // the vowels    vector<int> indices;     for (int i = 0; i < n; i++) {         if (s[i] == 'a' || s[i] == 'e'            || s[i] == 'o'            || s[i] == 'i'            || s[i] == 'u') {             counts[s[i]]++;            indices.push_back(i);        }    }     // If all vowels are not    // present in the string    if (counts.size() < 5)        return -1;     int flag1 = 0, flag2 = 0;    int i = 0;    int j = indices.size() - 1;     while ((j - i) >= 4) {         // If the frequency of the        // vowel at i-th index        // exceeds 1        if (!flag1            && counts[s[indices[i]]] > 1) {             // Decrease the frequency            // of that vowel            counts[s[indices[i]]]--;             // Move to the left            i++;        }         // Otherwise set flag1        else            flag1 = 1;         // If the frequency of the        // vowel at j-th index        // exceeds 1        if (!flag2            && counts[s[indices[j]]] > 1) {             // Decrease the frequency            // of that vowel            counts[s[indices[j]]]--;            // Move to the right            j--;        }         // Otherwise set flag2        else            flag2 = 1;         // If both flag1 and flag2        // are set, break out of the        // loop as the substring        // length cannot be minimized        if (flag1 && flag2)            break;    }     // Return the length of the substring    return (indices[j] - indices[i] + 1);} int main(){     string s = "aaeebbeaccaaoiuooooooooiuu";    cout << findMinLength(s);     return 0;}
// Java program to find the length of// the smallest substring of which// contains all vowelsimport java.util.*;class GFG{     public static int findMinLength(String s){    int n = s.length();      // Map to store the    // frequency of vowels    HashMap<Character,            Integer> counts = new HashMap<>();      // Store the indices    // which contains    // the vowels    Vector<Integer> indices = new Vector<Integer>();      for(int i = 0; i < n; i++)    {        if (s.charAt(i) == 'a' ||            s.charAt(i) == 'e' ||            s.charAt(i) == 'o' ||            s.charAt(i) == 'i' ||            s.charAt(i) == 'u')        {            if (counts.containsKey(s.charAt(i)))            {                counts.replace(s.charAt(i),                    counts.get(s.charAt(i)) + 1);            }            else            {                counts.put(s.charAt(i), 1);            }            indices.add(i);        }    }      // If all vowels are not    // present in the string    if (counts.size() < 5)        return -1;      int flag1 = 0, flag2 = 0;    int i = 0;    int j = indices.size() - 1;      while ((j - i) >= 4)    {                 // If the frequency of the        // vowel at i-th index        // exceeds 1        if (flag1 == 0 &&            counts.get(s.charAt(                indices.get(i))) > 1)        {                         // Decrease the frequency            // of that vowel            counts.replace(s.charAt(indices.get(i)),                counts.get(s.charAt(indices.get(i))) - 1);              // Move to the left            i++;        }          // Otherwise set flag1        else            flag1 = 1;          // If the frequency of the        // vowel at j-th index        // exceeds 1        if (flag2 == 0 &&            counts.get(s.charAt(                indices.get(j))) > 1)        {                         // Decrease the frequency            // of that vowel            counts.replace(s.charAt(indices.get(j)),                counts.get(s.charAt(indices.get(j))) - 1);                             // Move to the right            j--;        }          // Otherwise set flag2        else            flag2 = 1;          // If both flag1 and flag2        // are set, break out of the        // loop as the substring        // length cannot be minimized        if (flag1 == 1 && flag2 == 1)            break;    }         // Return the length of the substring    return (indices.get(j) - indices.get(i) + 1);} // Driver Codepublic static void main(String[] args){    String s = "aaeebbeaccaaoiuooooooooiuu";         System.out.print(findMinLength(s));}} // This code is contributed by divyeshrabadiya07
# Python3 program to find the# length of the smallest# substring of which# contains all vowelsfrom collections import defaultdict def findMinLength(s):     n = len(s)     # Map to store the    # frequency of vowels    counts = defaultdict(int)     # Store the indices    # which contains    # the vowels    indices = []     for i in range(n):         if (s[i] == 'a' or s[i] == 'e' or            s[i] == 'o' or s[i] == 'i' or            s[i] == 'u'):             counts[s[i]] += 1            indices.append(i)             # If all vowels are not    # present in the string    if len(counts) < 5:        return -1     flag1 = 0    flag2 = 0    i = 0    j = len(indices) - 1     while (j - i) >= 4:         # If the frequency of the        # vowel at i-th index        # exceeds 1        if (~flag1 and             counts[s[indices[i]]] > 1):             # Decrease the frequency            # of that vowel            counts[s[indices[i]]] -= 1             # Move to the left            i += 1         # Otherwise set flag1        else:            flag1 = 1         # If the frequency of the        # vowel at j-th index        # exceeds 1        if (~flag2 and             counts[s[indices[j]]] > 1):             # Decrease the frequency            # of that vowel            counts[s[indices[j]]] -= 1                         # Move to the right            j -= 1         # Otherwise set flag2        else:            flag2 = 1         # If both flag1 and flag2        # are set, break out of the        # loop as the substring        # length cannot be minimized        if (flag1 and flag2):            break     # Return the length of the substring    return (indices[j] - indices[i] + 1) # Driver Codes = "aaeebbeaccaaoiuooooooooiuu"print(findMinLength(s)) # This code is contributed by# divyamohan123
// C# program to find the length of// the smallest substring of which// contains all vowelsusing System;using System.Collections.Generic;class GFG{     public static int findMinLength(String s){  int n = s.Length;  int i = 0;     // Map to store the  // frequency of vowels  Dictionary<char,             int> counts = new Dictionary<char,                                          int>();   // Store the indices  // which contains  // the vowels  List<int> indices = new List<int>();   for(i = 0; i < n; i++)  {    if (s[i] == 'a' ||        s[i] == 'e' ||        s[i] == 'o' ||        s[i] == 'i' ||        s[i] == 'u')    {      if (counts.ContainsKey(s[i]))      {        counts[s[i]] = counts[s[i]] + 1;      }      else      {        counts.Add(s[i], 1);      }      indices.Add(i);    }  }   // If all vowels are not  // present in the string  if (counts.Count < 5)    return -1;   int flag1 = 0, flag2 = 0;  i = 0;  int j = indices.Count - 1;   while ((j - i) >= 4)  {    // If the frequency of the    // vowel at i-th index    // exceeds 1    if (flag1 == 0 &&        counts[s[indices[i]]] > 1)    {      // Decrease the frequency      // of that vowel      counts[s[indices[i]]]=             counts[s[indices[i]]] - 1;       // Move to the left      i++;    }     // Otherwise set flag1    else      flag1 = 1;     // If the frequency of the    // vowel at j-th index    // exceeds 1    if (flag2 == 0 &&        counts[s[indices[j]]] > 1)    {      // Decrease the frequency      // of that vowel      counts[s[indices[j]]] =             counts[s[indices[j]]] - 1;       // Move to the right      j--;    }     // Otherwise set flag2    else      flag2 = 1;     // If both flag1 and flag2    // are set, break out of the    // loop as the substring    // length cannot be minimized    if (flag1 == 1 && flag2 == 1)      break;  }   // Return the length of the substring  return (indices[j] - indices[i] + 1);} // Driver Codepublic static void Main(String[] args){  String s = "aaeebbeaccaaoiuooooooooiuu";  Console.Write(findMinLength(s));}} // This code is contributed by shikhasingrajput
<script> // JavaScript Program to find the// length of the smallest// substring of which// contains all vowels function findMinLength(s){    var n = s.length;     // Map to store the    // frequency of vowels    var counts = new Map();     // Store the indices    // which contains    // the vowels    var indices = [];     for (var i = 0; i < n; i++) {         if (s[i] == 'a' || s[i] == 'e'            || s[i] == 'o'            || s[i] == 'i'            || s[i] == 'u') {                             if(counts.has(s[i]))                    counts.set(s[i], counts.get(s[i])+1)                else                    counts.set(s[i], 1)            indices.push(i);        }    }     // If all vowels are not    // present in the string    if (counts.size < 5)        return -1;     var flag1 = 0, flag2 = 0;    var i = 0;    var j = indices.length - 1;     while ((j - i) >= 4) {         // If the frequency of the        // vowel at i-th index        // exceeds 1        if (!flag1            && counts.get(s[indices[i]]) > 1) {             // Decrease the frequency            // of that vowel            if(counts.has(s[indices[i]]))                    counts.set(s[indices[i]],                    counts.get(s[indices[i]])-1)                  // Move to the left            i++;        }         // Otherwise set flag1        else            flag1 = 1;         // If the frequency of the        // vowel at j-th index        // exceeds 1        if (!flag2            && counts.get(s[indices[j]]) > 1) {             // Decrease the frequency            // of that vowel            if(counts.has(s[indices[j]]))                    counts.set(s[indices[j]],                    counts.get(s[indices[j]])-1)            // Move to the right            j--;        }         // Otherwise set flag2        else            flag2 = 1;         // If both flag1 and flag2        // are set, break out of the        // loop as the substring        // length cannot be minimized        if (flag1 && flag2)            break;    }     // Return the length of the substring    return (indices[j] - indices[i] + 1);} var s = "aaeebbeaccaaoiuooooooooiuu";document.write( findMinLength(s));  </script>
9
 
Time Complexity: O(N) Auxiliary Space: O(N)
Sliding Window Approach:  
Maintain an array count to store the frequency of each vowel.
Maintain a start variable to store the starting index of the current substring.
Iterate over the string and do the following: Increase the frequency of the character if it is a vowel.Move start as right as possible based on the condition that either the character at the start is not a vowel or it is a vowel with a frequency greater than 1 which means that it has appeared previously.Once the start is moved as far as possible, check if all vowels are present in the substring between start and the current index.Whenever the above condition satisfies, update the minimum length of such substring obtained
Increase the frequency of the character if it is a vowel.
Move start as right as possible based on the condition that either the character at the start is not a vowel or it is a vowel with a frequency greater than 1 which means that it has appeared previously.
Once the start is moved as far as possible, check if all vowels are present in the substring between start and the current index.
Whenever the above condition satisfies, update the minimum length of such substring obtained
Print the minimum length of substring obtained or print -1 if no such substring is obtained
The below code implements the above approach: 
C++
Java
Python3
C#
Javascript
// C++ Program to find the// length of the smallest// substring of which// contains all vowels #include <bits/stdc++.h>using namespace std; // Function to return the// index for respective// vowels to increase their countint get_index(char ch){    if (ch == 'a')        return 0;    else if (ch == 'e')        return 1;    else if (ch == 'i')        return 2;    else if (ch == 'o')        return 3;    else if (ch == 'u')        return 4;     // Returns -1 for consonants    else        return -1;} // Function to find the minimum lengthint findMinLength(string s){    int n = s.size();    int ans = n + 1;     // Store the starting index    // of the current substring    int start = 0;     // Store the frequencies of vowels    int count[5] = { 0 };     for (int x = 0; x < n; x++) {         int idx = get_index(s[x]);         // If the current character        // is a vowel        if (idx != -1) {             // Increase its count            count[idx]++;        }         // Move start as much        // right as possible        int idx_start            = get_index(s[start]);         while (idx_start == -1               || count[idx_start] > 1) {             if (idx_start != -1) {                 count[idx_start]--;            }             start++;            if (start < n)                idx_start                    = get_index(s[start]);        }         // Condition for valid substring        if (count[0] > 0 && count[1] > 0            && count[2] > 0 && count[3] > 0            && count[4] > 0) {            ans = min(ans, x - start + 1);        }    }     if (ans == n + 1)        return -1;     return ans;} // Driver codeint main(){    string s = "aaeebbeaccaaoiuooooooooiuu";    cout << findMinLength(s);     return 0;}
// Java program to find the length// of the smallest subString of// which contains all vowelsimport java.util.*; class GFG{ // Function to return the// index for respective// vowels to increase their countstatic int get_index(char ch){    if (ch == 'a')        return 0;    else if (ch == 'e')        return 1;    else if (ch == 'i')        return 2;    else if (ch == 'o')        return 3;    else if (ch == 'u')        return 4;     // Returns -1 for consonants    else        return -1;} // Function to find the minimum lengthstatic int findMinLength(String s){    int n = s.length();    int ans = n + 1;     // Store the starting index    // of the current subString    int start = 0;     // Store the frequencies of vowels    int count[] = new int[5];     for(int x = 0; x < n; x++)    {       int idx = get_index(s.charAt(x));               // If the current character       // is a vowel       if (idx != -1)       {                       // Increase its count           count[idx]++;       }               // Move start as much       // right as possible       int idx_start = get_index(s.charAt(start));               while (idx_start == -1 ||              count[idx_start] > 1)       {           if (idx_start != -1)           {               count[idx_start]--;           }           start++;           if (start < n)               idx_start = get_index(s.charAt(start));       }               // Condition for valid subString       if (count[0] > 0 && count[1] > 0 &&           count[2] > 0 && count[3] > 0 &&           count[4] > 0)       {           ans = Math.min(ans, x - start + 1);       }    }    if (ans == n + 1)        return -1;     return ans;} // Driver codepublic static void main(String[] args){    String s = "aaeebbeaccaaoiuooooooooiuu";         System.out.print(findMinLength(s));}} // This code is contributed by 29AjayKumar
# Python3 Program to find the# length of the smallest# substring of which# contains all vowels # Function to return the# index for respective# vowels to increase their countdef get_index(ch):     if (ch == 'a'):        return 0    elif (ch == 'e'):        return 1    elif (ch == 'i'):        return 2    elif (ch == 'o'):        return 3    elif (ch == 'u'):        return 4     # Returns -1 for consonants    else:        return -1 # Function to find the minimum lengthdef findMinLength(s):     n = len(s)    ans = n + 1     # Store the starting index    # of the current substring    start = 0     # Store the frequencies    # of vowels    count = [0] * 5     for x in range (n):         idx = get_index(s[x])         # If the current character        # is a vowel        if (idx != -1):             # Increase its count            count[idx] += 1         # Move start as much        # right as possible        idx_start = get_index(s[start])         while (idx_start == -1 or               count[idx_start] > 1):             if (idx_start != -1):                 count[idx_start] -= 1             start += 1            if (start < n):                idx_start = get_index(s[start])         # Condition for valid substring        if (count[0] > 0 and count[1] > 0 and            count[2] > 0 and count[3] > 0 and            count[4] > 0):            ans = min(ans, x - start + 1)             if (ans == n + 1):        return -1    return ans # Driver codeif __name__ == "__main__":     s = "aaeebbeaccaaoiuooooooooiuu"    print(findMinLength(s))     # This code is contributed by Chitranayal
// C# program to find the length// of the smallest subString of// which contains all vowelsusing System;class GFG{ // Function to return the// index for respective// vowels to increase their countstatic int get_index(char ch){    if (ch == 'a')        return 0;    else if (ch == 'e')        return 1;    else if (ch == 'i')        return 2;    else if (ch == 'o')        return 3;    else if (ch == 'u')        return 4;     // Returns -1 for consonants    else        return -1;} // Function to find the minimum lengthstatic int findMinLength(String s){    int n = s.Length;    int ans = n + 1;     // Store the starting index    // of the current subString    int start = 0;     // Store the frequencies of vowels    int []count = new int[5];     for(int x = 0; x < n; x++)    {        int idx = get_index(s[x]);                     // If the current character        // is a vowel        if (idx != -1)        {                             // Increase its count            count[idx]++;        }                     // Move start as much        // right as possible        int idx_start = get_index(s[start]);                     while (idx_start == -1 ||               count[idx_start] > 1)        {            if (idx_start != -1)            {                count[idx_start]--;            }            start++;            if (start < n)                idx_start = get_index(s[start]);        }                     // Condition for valid subString        if (count[0] > 0 && count[1] > 0 &&            count[2] > 0 && count[3] > 0 &&            count[4] > 0)        {            ans = Math.Min(ans, x - start + 1);        }    }    if (ans == n + 1)        return -1;     return ans;} // Driver codepublic static void Main(String[] args){    String s = "aaeebbeaccaaoiuooooooooiuu";         Console.Write(findMinLength(s));}} // This code is contributed by sapnasingh4991
<script>// Javascript program to find the length// of the smallest subString of// which contains all vowels // Function to return the// index for respective// vowels to increase their countfunction get_index(ch){    if (ch == 'a')        return 0;    else if (ch == 'e')        return 1;    else if (ch == 'i')        return 2;    else if (ch == 'o')        return 3;    else if (ch == 'u')        return 4;      // Returns -1 for consonants    else        return -1;} // Function to find the minimum lengthfunction findMinLength(s){    let n = s.length;    let ans = n + 1;      // Store the starting index    // of the current subString    let start = 0;      // Store the frequencies of vowels    let count = new Array(5);     for(let i = 0; i < 5; i++)    {        count[i] = 0;    }         for(let x = 0; x < n; x++)    {       let idx = get_index(s[x]);                // If the current character       // is a vowel       if (idx != -1)       {                        // Increase its count           count[idx]++;       }                // Move start as much       // right as possible       let idx_start = get_index(s[start]);                while (idx_start == -1 ||              count[idx_start] > 1)       {           if (idx_start != -1)           {               count[idx_start]--;           }           start++;           if (start < n)               idx_start = get_index(s[start]);       }                // Condition for valid subString       if (count[0] > 0 && count[1] > 0 &&           count[2] > 0 && count[3] > 0 &&           count[4] > 0)       {           ans = Math.min(ans, x - start + 1);       }    }    if (ans == n + 1)        return -1;      return ans;} // Driver codelet s = "aaeebbeaccaaoiuooooooooiuu";document.write(findMinLength(s)); // This code is contributed by avanitrachhadiya2155</script>
9
 
Time Complexity: O(N) 
divyamohan123
29AjayKumar
sapnasingh4991
nidhi_biet
ukasp
divyeshrabadiya07
shikhasingrajput
rutvik_56
avanitrachhadiya2155
sliding-window
substring
two-pointer-algorithm
vowel-consonant
Competitive Programming
Hash
Strings
Write From Home
sliding-window
two-pointer-algorithm
Hash
Strings
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Multistage Graph (Shortest Path)
Breadth First Traversal ( BFS ) on a 2D array
Shortest path in a directed graph by Dijkstra’s algorithm
5 Best Books for Competitive Programming
Check whether bitwise AND of a number with any subset of an array is zero or not
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
Internal Working of HashMap in Java
Count pairs with given sum
Hashing | Set 1 (Introduction)
Hashing | Set 3 (Open Addressing)