📌  相关文章
📜  包含所有元音的最小子串的长度

📅  最后修改于: 2021-10-27 08:16:52             🧑  作者: Mango

给定仅由小写英文字母组成的字符串str ,任务是找到包含所有元音的最小长度的子字符串。如果找不到这样的子字符串,则打印-1

例子:

两个指针方法

  • 存储每个元音的频率和元音出现的索引。
  • 如果所有元音都不存在,直接打印-1。
  • 在包含元音的第一个和最后一个索引处取两个指针ij
  • 如果第 ij索引处的元音频率超过 1,则减少该元音的计数并将ij分别向右和向左移动到下一个包含元音的索引。
  • 如果第ij索引处的元音频率等于 1,分别设置flag1flag2并继续。
  • 一旦 flag1 和 flag2 都被设置,子串的长度就不能再被最小化了。两个指针指向的当前索引之间的距离表示结果。

下面的代码是上述方法的实现:

C++
// C++ Program to find the
// length of the smallest
// substring of which
// contains all vowels
 
#include 
using namespace std;
 
int findMinLength(string s)
{
    int n = s.size();
 
    // Map to store the
    // frequency of vowels
    map counts;
 
    // Store the indices
    // which contains
    // the vowels
    vector 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
// Java program to find the length of
// the smallest substring of which
// contains all vowels
import java.util.*;
class GFG{
     
public static int findMinLength(String s)
{
    int n = s.length();
  
    // Map to store the
    // frequency of vowels
    HashMap counts = new HashMap<>();
  
    // Store the indices
    // which contains
    // the vowels
    Vector indices = new Vector();
  
    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 Code
public static void main(String[] args)
{
    String s = "aaeebbeaccaaoiuooooooooiuu";
     
    System.out.print(findMinLength(s));
}
}
 
// This code is contributed by divyeshrabadiya07


Python3
# Python3 program to find the
# length of the smallest
# substring of which
# contains all vowels
from 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 Code
s = "aaeebbeaccaaoiuooooooooiuu"
print(findMinLength(s))
 
# This code is contributed by
# divyamohan123


C#
// C# program to find the length of
// the smallest substring of which
// contains all vowels
using 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 counts = new Dictionary();
 
  // Store the indices
  // which contains
  // the vowels
  List indices = new List();
 
  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 Code
public static void Main(String[] args)
{
  String s = "aaeebbeaccaaoiuooooooooiuu";
  Console.Write(findMinLength(s));
}
}
 
// This code is contributed by shikhasingrajput


Javascript


C++
// C++ Program to find the
// length of the smallest
// substring of which
// contains all vowels
 
#include 
using namespace std;
 
// Function to return the
// index for respective
// vowels to increase their count
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 length
int 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 code
int main()
{
    string s = "aaeebbeaccaaoiuooooooooiuu";
    cout << findMinLength(s);
 
    return 0;
}


Java
// Java program to find the length
// of the smallest subString of
// which contains all vowels
import java.util.*;
 
class GFG{
 
// Function to return the
// index for respective
// vowels to increase their count
static 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 length
static 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 code
public static void main(String[] args)
{
    String s = "aaeebbeaccaaoiuooooooooiuu";
     
    System.out.print(findMinLength(s));
}
}
 
// This code is contributed by 29AjayKumar


Python3
# 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 count
def 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 length
def 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 code
if __name__ == "__main__":
 
    s = "aaeebbeaccaaoiuooooooooiuu"
    print(findMinLength(s))
     
# This code is contributed by Chitranayal


C#
// C# program to find the length
// of the smallest subString of
// which contains all vowels
using System;
class GFG{
 
// Function to return the
// index for respective
// vowels to increase their count
static 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 length
static 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 code
public static void Main(String[] args)
{
    String s = "aaeebbeaccaaoiuooooooooiuu";
     
    Console.Write(findMinLength(s));
}
}
 
// This code is contributed by sapnasingh4991


Javascript


输出:
9

时间复杂度: O(N)
辅助空间: O(N)

滑动窗口方法

  • 维护一个数组计数来存储每个元音的频率。
  • 维护一个起始变量来存储当前子串的起始索引。
  • 遍历字符串并执行以下操作:
    • 如果是元音,则增加字符的频率。
    • 根据开头的字符不是元音或者是频率大于 1 的元音(这意味着它之前出现过)的条件,将 start 尽可能向右移动。
    • 一旦开始尽可能地移动,检查开始和当前索引之间的子字符串中是否存在所有元音。
    • 每当满足上述条件时,更新获得的此类子串的最小长度
  • 打印获得的子串的最小长度或如果没有获得这样的子串则打印-1

下面的代码实现了上述方法:

C++

// C++ Program to find the
// length of the smallest
// substring of which
// contains all vowels
 
#include 
using namespace std;
 
// Function to return the
// index for respective
// vowels to increase their count
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 length
int 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 code
int main()
{
    string s = "aaeebbeaccaaoiuooooooooiuu";
    cout << findMinLength(s);
 
    return 0;
}

Java

// Java program to find the length
// of the smallest subString of
// which contains all vowels
import java.util.*;
 
class GFG{
 
// Function to return the
// index for respective
// vowels to increase their count
static 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 length
static 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 code
public static void main(String[] args)
{
    String s = "aaeebbeaccaaoiuooooooooiuu";
     
    System.out.print(findMinLength(s));
}
}
 
// This code is contributed by 29AjayKumar

蟒蛇3

# 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 count
def 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 length
def 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 code
if __name__ == "__main__":
 
    s = "aaeebbeaccaaoiuooooooooiuu"
    print(findMinLength(s))
     
# This code is contributed by Chitranayal

C#

// C# program to find the length
// of the smallest subString of
// which contains all vowels
using System;
class GFG{
 
// Function to return the
// index for respective
// vowels to increase their count
static 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 length
static 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 code
public static void Main(String[] args)
{
    String s = "aaeebbeaccaaoiuooooooooiuu";
     
    Console.Write(findMinLength(s));
}
}
 
// This code is contributed by sapnasingh4991

Javascript


输出:
9

时间复杂度: O(N)