Longest substring having K distinct vowels

Given a string s we have to find the length of the longest substring of s which contain exactly K distinct vowels.
Note: Consider uppercase and lowercase characters as two different characters.

Examples:

Input : s = “tHeracEBetwEEntheTwo”, k = 1
Output : 14
Explanation : Longest substring with only 1 vowel is “cEBetwEEntheTw”
and its length is 14.



Input : s = “artyebui”, k = 2
Output : 6
Explanation : Longest substring with only 2 vowel is “rtyebu”

Brute-Force Approach: For each substring, we check for the criteria for K distinct vowel and check the length. Finally, the largest length will be the result.

Efficient Approach : Here we maintain the count of vowels occurring in the substring. Till K is not zero, we count the distinct vowel occurring in the substring. As K becomes negative, we start deleting the first vowel of the substring we have found till that time, so that it may be possible that new substring( larger length ) is possible afterward. As we delete the vowel we decrease its count so that new substring may contain that vowel occurring in the later part of the string. And as K is 0 we get the length of the substring.

Below is the implementation of the above approach

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// CPP program to find the longest substring
// with k distinct vowels.
#include <bits/stdc++.h>
using namespace std;
  
#define MAX 128
  
// Function to check whether a character is
// vowel or not
bool isVowel(char x)
{
    return (x == 'a' || x == 'e' || x == 'i' ||
            x == 'o' || x == 'u' || x == 'A' || 
            x == 'E' || x == 'I' || x == 'O' ||
            x == 'U');
}
  
int KDistinctVowel(char s[], int k)
{
    // length of string
    int n = strlen(s);
  
    // array for count of characters
    int c[MAX];
    memset(c, 0, sizeof(c));
  
    // Initialize result to be
    // negative
    int result = -1;
  
    for (int i = 0, j = -1; i < n; ++i) {
  
        int x = s[i];
  
        // If letter is vowel then we
        // increment its count value
        // and decrease the k value so
        // that if we again encounter the
        // same vowel character then we
        // don't consider it for our result
        if (isVowel(x)) {
            if (++c[x] == 1) {
  
                // Decrementing the K value
                --k;
            }
        }
  
        // Till k is 0 above if condition run
        // after that this while loop condition
        // also become active. Here what we have
        // done actually is that, if K is less
        // than 0 then we eliminate the first
        // vowel we have encountered till that
        // time . Now K is incremented and k
        // becomes 0. So, now we calculate the
        // length of substring from the present
        // index to the deleted index of vowel
        // which result in our results.
        while (k < 0) {
  
            x = s[++j];
            if (isVowel(x)) {
  
                // decresing the count
                // so that it may appear
                // in another substring
                // appearing after this
                // present substring
                if (--c[x] == 0) {
  
                    // incrementing the K value
                    ++k;
                }
            }
        }
  
        // Checking the maximum value
        // of the result by comparing
        // the length of substring
        // whenever K value is 0 means
        // K distinct vowel is present
        // in substring
        if (k == 0) 
            result = max(result, i - j);        
    }
    return result;
}
  
// Driver code
int main(void)
{
    char s[] = "tHeracEBetwEEntheTwo";
    int k = 1;
    cout << KDistinctVowel(s, k);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find the longest substring 
// with k distinct vowels. 
  
class GFG {
  
    static int MAX = 128;
  
    // Function to check whether a character is 
    // vowel or not 
    static boolean isVowel(char x) {
        return (x == 'a' || x == 'e' || x == 'i' ||
                x == 'o' || x == 'u' || x == 'A' ||
                x == 'E' || x == 'I' || x == 'O' ||
                x == 'U');
    }
  
    static int KDistinctVowel(String s, int k) {
        // length of string 
        int n = s.length();
  
        // array for count of characters 
        int[] c = new int[MAX];
        //Array.Clear(c, 0, c.Length); 
  
        // Initialize result to be 
        // negative 
        int result = -1;
  
        for (int i = 0, j = -1; i < n; ++i) {
  
            char x = s.charAt(i);
  
            // If letter is vowel then we 
            // increment its count value 
            // and decrease the k value so 
            // that if we again encounter the 
            // same vowel character then we 
            // don't consider it for our result 
            if (isVowel(x)) {
                if (++c[x] == 1) {
  
                    // Decrementing the K value 
                    --k;
                }
            }
  
            // Till k is 0 above if condition run 
            // after that this while loop condition 
            // also become active. Here what we have 
            // done actually is that, if K is less 
            // than 0 then we eliminate the first 
            // vowel we have encountered till that 
            // time . Now K is incremented and k 
            // becomes 0. So, now we calculate the 
            // length of substring from the present 
            // index to the deleted index of vowel 
            // which result in our results. 
            while (k < 0) {
  
                x = s.charAt(++j);
                if (isVowel(x)) {
  
                    // decresing the count 
                    // so that it may appear 
                    // in another substring 
                    // appearing after this 
                    // present substring 
                    if (--c[x] == 0) {
  
                        // incrementing the K value 
                        ++k;
                    }
                }
            }
  
            // Checking the maximum value 
            // of the result by comparing 
            // the length of substring 
            // whenever K value is 0 means 
            // K distinct vowel is present 
            // in substring 
            if (k == 0) {
                result = Math.max(result, i - j);
            }
        }
        return result;
    }
  
    // Driver code 
    public static void main(String[] args) {
        String s = "tHeracEBetwEEntheTwo";
        int k = 1;
        System.out.println(KDistinctVowel(s, k));
    }
}
  
/* This Java code is contributed by Rajput-Ji*/

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to find the longest substring
# with k distinct vowels.
  
MAX = 128
  
# Function to check whether a character is
# vowel or not
def isVowel(x):
  
    return (x == 'a' or x == 'e' or x == 'i' or
            x == 'o' or x == 'u' or x == 'A' or
            x == 'E' or x == 'I' or x == 'O' or
            x == 'U')
  
def KDistinctVowel(c,k):
    n = len(s)
  
    c = [0 for i in range(MAX)]
    result = -1
  
    j = -1
  
    for i in range(n):
        x=s[i]
  
        # If letter is vowel then we
        # increment its count value
        # and decrease the k value so
        # that if we again encounter the
        # same vowel character then we
        # don't consider it for our result
  
        if isVowel(x):
            c[ord(x)] += 1
            if c[ord(x)] == 1:
                k -= 1
  
        # Till k is 0 above if condition run
        # after that this while loop condition
        # also become active. Here what we have
        # done actually is that, if K is less
        # than 0 then we eliminate the first
        # vowel we have encountered till that
        # time . Now K is incremented and k
        # becomes 0. So, now we calculate the
        # length of substring from the present
        # index to the deleted index of vowel
        # which result in our results.
        while k < 0:
            j += 1
            x = s[j]
            if isVowel(x): 
                  
                # decresing the count
                # so that it may appear
                # in another substring
                # appearing after this
                # present substring
                c[ord(x)] -= 1
                k += 1 
                  
        # Checking the maximum value
        # of the result by comparing
        # the length of substring
        # whenever K value is 0 means
        # K distinct vowel is present
        # in substring     
  
        if k == 0:
            result = max(result, i - j)
  
    return result
  
s = "tHeracEBetwEEntheTwo"
k = 1
print(KDistinctVowel(s, k))
  
# This code is contributed by mohit kumar 29

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find the longest substring
// with k distinct vowels.
using System;
  
class GFG {
      
    static int MAX = 128;
      
    // Function to check whether a character is
    // vowel or not
    static bool isVowel(char x)
    {
        return (x == 'a' || x == 'e' || x == 'i' ||
                x == 'o' || x == 'u' || x == 'A' || 
                x == 'E' || x == 'I' || x == 'O' ||
                x == 'U');
    }
      
    static int KDistinctVowel(string s, int k)
    {
        // length of string
        int n = s.Length;
      
        // array for count of characters
        int []c = new int[MAX];
        Array.Clear(c, 0, c.Length);
      
        // Initialize result to be
        // negative
        int result = -1;
      
        for (int i = 0, j = -1; i < n; ++i) {
      
            char x = s[i];
      
            // If letter is vowel then we
            // increment its count value
            // and decrease the k value so
            // that if we again encounter the
            // same vowel character then we
            // don't consider it for our result
            if (isVowel(x)) {
                if (++c[x] == 1) {
      
                    // Decrementing the K value
                    --k;
                }
            }
      
            // Till k is 0 above if condition run
            // after that this while loop condition
            // also become active. Here what we have
            // done actually is that, if K is less
            // than 0 then we eliminate the first
            // vowel we have encountered till that
            // time . Now K is incremented and k
            // becomes 0. So, now we calculate the
            // length of substring from the present
            // index to the deleted index of vowel
            // which result in our results.
            while (k < 0) {
      
                x = s[++j];
                if (isVowel(x)) {
      
                    // decresing the count
                    // so that it may appear
                    // in another substring
                    // appearing after this
                    // present substring
                    if (--c[x] == 0) {
      
                        // incrementing the K value
                        ++k;
                    }
                }
            }
      
            // Checking the maximum value
            // of the result by comparing
            // the length of substring
            // whenever K value is 0 means
            // K distinct vowel is present
            // in substring
            if (k == 0) {
                result = Math.Max(result, i - j);
            }
        }
        return result;
    }
      
    // Driver code
    static void Main()
    {
        string s = "tHeracEBetwEEntheTwo";
        int k = 1;
        Console.Write(KDistinctVowel(s, k));
    }
}
  
// This code is contributed Manish Shaw
// (manishshaw1)

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php 
// PHP program to find the longest 
// substring with k distinct vowels.
$MAX = 128;
  
// Function to check whether a 
// character is vowel or not
function isVowel($x)
{
    return ($x == 'a' || $x == 'e' || $x == 'i' ||
            $x == 'o' || $x == 'u' || $x == 'A' || 
            $x == 'E' || $x == 'I' || $x == 'O' ||
            $x == 'U');
}
  
function KDistinctVowel($s, $k)
{
    global $MAX;
      
    // length of string
    $n = strlen($s);
  
    // array for count of characters
    $c = array_fill(0, $MAX, NULL);
  
    // Initialize result to be negative
    $result = -1;
  
    for ($i = 0, $j = -1; $i < $n; ++$i
    {
        $x = $s[$i];
  
        // If letter is vowel then we increment 
        // its count value and decrease the k 
        // value so that if we again encounter 
        // the same vowel character then we
        // don't consider it for our result
        if (isVowel($x)) 
        {
            if (++$c[ord($x)] == 1) 
            {
  
                // Decrementing the K value
                --$k;
            }
        }
  
        // Till k is 0 above if condition run
        // after that this while loop condition
        // also become active. Here what we have
        // done actually is that, if K is less
        // than 0 then we eliminate the first
        // vowel we have encountered till that
        // time . Now K is incremented and k
        // becomes 0. So, now we calculate the
        // length of substring from the present
        // index to the deleted index of vowel
        // which result in our results.
        while ($k < 0) 
        {
            $x = $s[++$j];
            if (isVowel($x)) 
            {
  
                // decresing the count so that it 
                // may appear in another substring
                // appearing after this present 
                // substring
                if (--$c[ord($x)] == 0) 
                {
  
                    // incrementing the K value
                    ++$k;
                }
            }
        }
  
        // Checking the maximum value of the 
        // result by comparing the length of 
        // substring whenever K value is 0 
        // means K distinct vowel is present
        // in substring
        if ($k == 0) 
            $result = max($result, $i - $j);     
    }
    return $result;
}
  
// Driver code
$s = "tHeracEBetwEEntheTwo";
$k = 1;
echo KDistinctVowel($s, $k);
  
// This code is contributed by ita_c
?>

chevron_right


Output:

7


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.