Count of substrings containing exactly K distinct vowels


In this problem, we need to count the total number of substrings of string str containing exactly K distinct vowels. We can solve the problem in two different ways. The first approach is to traverse all substrings and count the number of vowels in each substring. We can also use the map data structure to optimize the code of the first approach.

Problem statement – We have given string str of length N. The string contains uppercase and lowercase alphabetical characters. Also, we have given integer K. We need to find the total number of substrings of str containing exactly K distinct vowels.

Note – Here, we assume that ‘a’ and ‘A’ are equal.

Sample examples

Input – str = “point”, K = 2

Output – 6

Explanation– The substrings of str, which contains exactly 2 vowels, are: ‘poi’, ‘oin’, ‘oint’, ‘poin’, ‘point’, and ‘oi’.

Input – str = ‘abcurso’, K = 3

Output – 1

Explanation – The substrings of str, which contains exactly 3 vowels, is str itself.

Input – str = ‘aeiofd’, K = 5

Output – 0

Explanation – As a string contains only 4 vowels, we need a substring containing 5. So, it is not possible to find any substring.

Approach 1

In this approach, we will get substrings of length 1 to N. We will check the total number of vowels in each substring. If we find that any substring contains exactly K vowels, we will increment the count value by 1.

Algorithm

  • Define the ‘cnt’ variable to store the count of substrings according to given conditions and ‘len’ to store the length of the string.

  • Use two nested loops to cover all substrings of str.

  • Get the substring starting from the ith index and have (q – p + 1) length.

  • Use the cntDistVowel() function to count distinct vowels in the substring.

    • In the cntDistVowel() function, define the map.

    • Convert the string to lowercase using the transform() method.

    • Traverse the string and update the map value for each character in the string. Update value from 0 to 1.

    • Return the sum of values of the ‘a’, ‘e’, ‘I’, ‘o’, ‘u’ keys from the map.

  • In the countKSub() function, if ‘dis_vowel’ is equal to the K, increase the value of ‘cnt’ by 1.

  • Return ‘cnt’ value.

Example

#include <bits/stdc++.h>
using namespace std;
int cntDistVowel(string sub) {
   // creating unordered_map to store vowels present in substring
   unordered_map<char, int> mp;
   // convert sub to lowercase
   transform(sub.begin(), sub.end(), sub.begin(), ::tolower);
   // traverse the substring
   for (int p = 0; p < sub.length(); p++) {
      mp[sub[p]] = 1;
   }
   // return total number of distinct vowels
   return mp['a'] + mp['e'] + mp['i'] + mp['o'] + mp['u'];
}
int countkSubs(string str, int k) {
   // to store the total number of substrings
   int cnt = 0;
   int len = str.length();
   // traverse the string
   for (int p = 0; p < len; p++) {
      for (int q = p; q < len; q++) {
          // get the substring from p to q
          string sub = str.substr(p, q - p + 1);
          // count distinct vowels in the substring
          int dis_vowel = cntDistVowel(sub);
          // if the number of distinct vowels equals k then increment cnt by 1
          if (dis_vowel == k)
             cnt++;
      }
   }
   return cnt;
}
int main() {
   string str = "point";
   int K = 2;
   cout << "The number of substrings containing exactly " << K << " vowels is " << countkSubs(str, K) << endl;
   return 0;
}

Output

The number of substrings containing exactly 2 vowels is 6

Time complexity – O(N*N*N). Here, O(N*N) is for finding all substrings, and O(N) is for counting distinct vowels in the substring of maximum length N.

Space complexity – O(N), as we use the ‘sub’ variable to store the substring.

Approach 2

This approach contains an optimized version of the above code. Here, we update the character present in the map while traversing through the substring starting from the ith index. When we find any substring containing exactly K vowels, we update the count value.

Algorithm

  • Initialize the ‘cnt’ and ‘len’ variables.

  • Use the loop to traverse the string str.

  • Define the ‘dist_vowel’ variable to store total distinct vowels in the substring starting from index p. Also, define the list of 26 to store the presence of vowels in the substring

  • Use the nested loop to get the i and j index substring.

  • use the tolower() function to convert the character to lowercase and store it into the ‘temp’ variable.

  • – Use the isVowel() function to check whether the current character is bowel. If yes, and not present in the map, increase the value of dist_vowel by 1. Also, update the value of the map.

  • If the value of ‘disst_vowel’ is equal to K, increase the value of ‘cnt’.

  • If the value of ‘dist_vowel’ is greater than K, break the nested loop.

  • Return the value of ‘cnt’.

Example

#include <bits/stdc++.h>
using namespace std;
bool isVowel(char ch) {
   return (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' );
}
int countkSubs(string alpha, int k) {
   int len = alpha.length();
   // Initialize the count
   int cnt = 0;
   // Cover all substrings
   for (int p = 0; p < len; p++) {
      // To store the count of distinct vowels
      int dist_vowel = 0;
      // to store the count of characters
      vector<int> map(26, 0);
      // get a substring from p to q
      for (int q = p; q < len; q++) {
          char temp = tolower(alpha[q]);
          // If the current character is a vowel and new, increment dist_vowel by 1
          if (isVowel(temp) && map[temp - 'a'] == 0)
              dist_vowel++;
          // Increase the character count by 1
          map[temp - 'a']++;
          // If the number of distinct vowels is k, increment count by 1
          if (dist_vowel == k)
              cnt++;
          // If the number of distinct vowels is more than k, break
          if (dist_vowel > k)
              break;
       }
   }
   return cnt;
}
int main() {
   string alpha = "point";
   int K = 2;
   cout << "The number of substrings containing exactly " << K << " vowels is " << countkSubs(alpha, K) << endl;
   return 0;
}

Output

The number of substrings containing exactly 2 vowels is 6

Time complexity – O(N*N), as we use nested loops.

Space complexity – O(26) ~ O(1) as we use to store the presence of vowel in the substring.

We learned two approaches to solving the problem. The first approach is the naïve approach, and the second is optimized. Here, we solved the problem of counting substrings containing exactly K distinct vowels. Programmers can solve the problem of counting a number of substrings containing exactly K vowels.

Updated on: 17-Aug-2023

107 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements