Count of substrings formed using a given set of characters only

Given a string str and an array arr[] of K characters, the task is to find the number of substrings of str that contains characters only from the given character array arr[].

Note: The string str and the arr[] contains only lowercase alphabets.

Examples:

Input: S = “abcb”, K = 2, charArray[] = {‘a’, ‘b’}
Output: 4
Explanation:
The substrings are “a”, “ab”, “b”, “b” using the available characters

Input: S = “aabdbbtr”, K = 4, charArray[] = {‘e’, ‘a’, ‘r’, ‘t’}
Output: 6
Explanation:
The substrings “a”, “aa”, “a”, “t”, “tr”, “r” using the available characters.



Naive Approach: The naive approach is generate all possible subtrings for the given string str and check if each substring consists of given characters in the array arr[] or not. If Yes then count that substring else check for the next substring.

Time Complexity: O(N2)
Auxiliary Space: O(N)

Efficient Approach: The above naive approach can be optimized as we will delete the count of substrings formed by character which are not present in the given array arr[]. Below are the steps:

  1. Store the characters present in the array arr[] in a boolean array of size 26, so that the searching of any character can be done in O(1) time.
  2. The total number of substrings formed by string of length N is (N*(N+1))/2, initialise count as (N*(N+1))/2.
  3. Traverse the string from left to right and store the index of the last character that we encountered in the string which is not present in the array arr[] using a variable lastPos
  4. If while traversing the string we encounter any character that is not present in arr[] then we subtract number of substrings that will contain this character and will have a starting point greater than the value of lastPos. Suppose we are at index i then the number of substrings to be substracted will be given by
    (i - lastPos)*(N - i)
    
  5. Update the value of lastPos everytime we encounter a character not available in charArray[].
    1. Below is the implementation of the above approach:

      C++

      filter_none

      edit
      close

      play_arrow

      link
      brightness_4
      code

      // C++ program for the above approach
      #include <bits/stdc++.h>
      using namespace std;
        
      // Function to find the number of
      // substrings that can be formed
      // using given characters
      void numberofsubstrings(string str, int k,
                              char charArray[])
      {
          int N = str.length();
        
          // Boolean array for storing
          // the available characters
          bool available[26] = { 0 };
        
          // Mark indices of all
          // available characters as 1
          for (int i = 0; i < k; i++) {
              available[charArray[i] - 'a'] = 1;
          }
        
          // Intialize lastPos as -1
          int lastPos = -1;
        
          // Initialize ans with the total
          // no of possible substrings
          int ans = (N * (N + 1)) / 2;
        
          // Traverse the string from
          // left to right
          for (int i = 0; i < N; i++) {
        
              // If the current character
              // is not present in B
              if (available[str[i] - 'a'] == 0) {
        
                  // Subtract the total possible
                  // substrings
                  ans -= ((i - lastPos)
                          * (N - i));
        
                  // Update the value of
                  // lastpos to current index
                  lastPos = i;
              }
          }
        
          // Print the final answer
          cout << ans << endl;
      }
        
      // Driver Code
      int main()
      {
          // Given String
          string str = "abcb";
          int k = 2;
        
          // Given character array
          char charArray[k] = { 'a', 'b' };
        
          // Function Call
          numberofsubstrings(str, k, charArray);
          return 0;
      }

      chevron_right

      
      

      Java

      filter_none

      edit
      close

      play_arrow

      link
      brightness_4
      code

      // Java program for the above approach
      import java.util.Arrays;
        
      class GFG{
            
      // Function to find the number of
      // substrings that can be formed
      // using given characters
      public static void numberofsubstrings(String str, int k,
                                            char charArray[])
      {
          int N = str.length();
        
          // Boolean array for storing
          // the available characters
          int available[] = new int[26];
          Arrays.fill(available, 0);
        
          // Mark indices of all
          // available characters as 1
          for(int i = 0; i < k; i++)
          {
             available[charArray[i] - 'a'] = 1;
          }
        
          // Initialize lastPos as -1
          int lastPos = -1;
        
          // Initialize ans with the total
          // no of possible substrings
          int ans = (N * (N + 1)) / 2;
        
          // Traverse the string from
          // left to right
          for(int i = 0; i < N; i++)
          {
               
             // If the current character
             // is not present in B
             if (available[str.charAt(i) - 'a'] == 0)
             {
                   
                 // Subtract the total possible
                 // substrings
                 ans -= ((i - lastPos) * (N - i));
                   
                 // Update the value of
                 // lastpos to current index
                 lastPos = i;
             }
          }
            
          // Print the final answer
          System.out.println(ans);
      }
        
      // Driver Code
      public static void main(String args[])
      {
            
          // Given String
          String str = "abcb";
          int k = 2;
        
          // Given character array
          char []charArray = {'a', 'b'};
        
          // Function Call
          numberofsubstrings(str, k, charArray);
      }
      }
        
      // This code is contributed by SoumikMondal

      chevron_right

      
      

      C#

      filter_none

      edit
      close

      play_arrow

      link
      brightness_4
      code

      // C# program for the above approach
      using System;
        
      class GFG{
            
      // Function to find the number of
      // substrings that can be formed
      // using given characters
      public static void numberofsubstrings(String str, int k,
                                            char []charArray)
      {
          int N = str.Length;
        
          // Boolean array for storing
          // the available characters
          int []available = new int[26];
        
          // Mark indices of all
          // available characters as 1
          for(int i = 0; i < k; i++)
          {
             available[charArray[i] - 'a'] = 1;
          }
        
          // Initialize lastPos as -1
          int lastPos = -1;
        
          // Initialize ans with the total
          // no of possible substrings
          int ans = (N * (N + 1)) / 2;
        
          // Traverse the string from
          // left to right
          for(int i = 0; i < N; i++)
          {
               
             // If the current character
             // is not present in B
             if (available[str[i] - 'a'] == 0)
             {
        
                 // Subtract the total possible
                 // substrings
                 ans -= ((i - lastPos) * (N - i));
                   
                 // Update the value of
                 // lastpos to current index
                 lastPos = i;
             }
          }
            
          // Print the final answer
          Console.WriteLine(ans);
      }
        
      // Driver Code
      public static void Main(String []args)
      {
            
          // Given String
          String str = "abcb";
          int k = 2;
        
          // Given character array
          char []charArray = {'a', 'b'};
        
          // Function Call
          numberofsubstrings(str, k, charArray);
      }
      }
        
      // This code is contributed by Princi Singh

      chevron_right

      
      

      Output:

      4
      

      Time Complexity: O(N), N is the length of the string
      Auxiliary Space: O(1)

      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.



      Improved By : SoumikMondal, princi singh