Last Updated: 14 Jul, 2022

Subsequence Game

Moderate
Asked in company
Google inc

Problem statement

Shail is very fond of strings. So his parents on his birthday gave him a task on strings as a present. The task is as follows:

There is the main string ‘STR’ of length ‘N’ consisting of only lowercase English letters, and there is an array of strings ‘ARR’ of length ‘M’, where each string consists of only lowercase English letters. Now Shail has to find the count of such strings in the array ‘ARR’ which occurs as a subsequence in the string ‘STR’ and tell it to their parents.

But Shail is busy with his birthday celebration and cannot solve the task, but want to make his parents happy by giving them the answer to the task, So being his friend he asked you to solve this problem, Can you help him?.

NOTE: A subsequence of a given sequence, is a sequence that can be derived from the given sequence by deleting some or no elements without changing the order of the remaining elements. For more details please visit this link.

EXAMPLE :
Input: ‘N’ = 5, ‘M' = 2, ‘STR’ = “abcde” , ‘ARR’ = [“ad”, “cb”]

Output: 1
In this case, string “ad” occurs as a subsequence in the string ‘STR’ and the index of the match is ‘0’ and ‘3’ respectively. Also, string “cb” isn’t a subsequence because there is no occurrence of ‘b’ after the first ‘c’ at index ‘2’. Hence the output will be ‘1’.
Input Format :
The first line will contain the integer ‘T’, the number of test cases.

The first line of each test case contains two integers, ‘N’ and ‘M’ , denoting the length of string and array respectively.

Followed by a line containing the string ‘STR’ of length.

Followed by ‘M’ lines, each containing the string of the array ‘ARR’. 
Output format :
For each test case, print the count of strings in the array ‘ARR’ that occurs as a subsequence in the string ‘STR’.
Note :
You don't need to print anything. It has already been taken care of. Just implement the given function.
Constraints :
1 <= ‘T’ <= 10
1 <= ‘N’ <= 10^4
STR.length = N
1 <= ‘M’ <= 10^4
‘STR’ only consists of lowercase English letters.
It is guaranteed that sum of ‘N’ over all test cases is <= 10^5
It is guaranteed that sum of lengths of strings in array ‘ARR’ over all test cases is <= 10^5
Time Limit: 1 sec

Approaches

01 Approach

The idea for this approach is to maintain the index of the matching element. So for every string of array ‘ARR’, we will start out iteration from ‘0’ up to ‘N-1’ for string ‘STR’, let's denote the current index of iteration to be ‘i’. Now for the string of array ‘ARR’ to be a subsequence of string ‘STR’, the order of characters should match, hence we can start with index ‘j = 0’ for the above iteration, and whenever ‘STR[i]’ matches the ‘jth’ index if the current string of ‘ARR’, we increment ‘j’. If at the end if ‘j’ is equal to the length of the current string of the array ‘ARR’, then we can say that the current string is a subsequence in string ‘STR’.

 

We will follow the same process for every string of ‘ARR’ and update the answer by ‘1’, whenever found a string that satisfies the above-mentioned condition.
 

Algorithm:
 

// The function will return the count of strings that are subsequence in the string ‘STR’.

Int subsequenceGame(N, M, STR, ARR)

  • Initialize the variable ‘ANS’ with the value ‘0’.
  • Run a for loop from ‘0’ to ‘M-1’ with a variable named ‘index’.
    • Initialize the variable ‘SIZE’ with the value of the length of the string ‘ARR[index]’.
    • Initialize the variable ‘j’ with the value ‘0’.
    • Run a for loop from ‘0’ to ‘N-1’ with a variable named ‘i’.
      • If ‘STR[i] == ARR[index][j]’
        • Increment ‘j’ by ‘1’.
        • If ‘j == SIZE’
          • Stop the loop.
    • If ‘j == SIZE’
      • Increment ‘ANS’ by ‘1’.
  • Return ‘ANS’.

02 Approach

In the previous approach, we are iterating on the string ‘STR’ again and again to check if the current string of array ‘ARR’ is a subsequence in it or not. Now to optimize that we can preprocess some information of string ‘STR’ in such a way that any string that is its subsequence can directly jump to the indexes that match it.

 

We can do this by dynamic programming, we will iterate on the string ‘STR’ in reverse order, by maintaining the nearest index of the occurrence of every alphabet from ‘a’ to ‘z’ for every ‘i’ ∈ ‘[0, N-1]’. We are storing the nearest index because we want to use the same information for all subsequences, hence we will try to use minimal characters in the string ‘STR’ to complete the string matching.

 

But as the approach will become complicated if we follow 0-based indexing, hence we will follow 1-based indexing for storing this information, we will first insert a non-English character at the start of the string ‘STR’ and then maintain the above-mentioned information for ‘i’ ∈ ‘[0, N]’, where each index ‘i’ will have the information about the nearest occurrence of every alphabet from ‘a’ to ‘z’ for the whole suffix ‘[i+1, N]’. To initialize the 2D ‘dp’ array we will give them the value of any index that is out of bound of string ‘STR’ i.e. (N+1).
 

In the below idea we consider the alphabets ‘a’ as ‘0’, ‘b’ as ‘1’, … and ‘z’ as ‘25’ when compared with a number.
 

Algorithm:
 

// The function will return the count of strings that are subsequence in the string ‘STR’.

Int subsequenceGame(N, M, STR, ARR)

  • Initialize the variable ‘ANS’ with the value ‘0’.
  • Initialize the variable ‘maxChar’ with the value ‘26’.
  • Create a 2D array named ‘DP’ with the dimensions ‘(N+1)*maxChar’ and with the initial value of ‘N+1’.
  • Insert a non-English character (i.e. ‘$’) at beginning of the string ‘STR’.
  • Run a for loop in reverse order from ‘N-1’ to ‘0’ with a variable named ‘i’.
    • Run a for loop from ‘0’ to ‘maxChar-1’ with a variable named ‘j’.
    • If ‘STR[i+1]’ is equal to the character represented by the number ‘j’.
      • Assign ‘DP[i][j]’ the value of ‘i+1’.
    • Else
      • Assign ‘DP[i][j]’ the value of ‘DP[i+1][j]’.
  • Run a for loop from ‘0’ to ‘M-1’ with a variable named ‘index’.
    • Initialize the variable ‘SIZE’ with the value of the length of the string ‘ARR[index]’.
    • Initialize the variable ‘j’ with the value ‘0’.
    • Initialize the variable ‘i’ with the value ‘0’.
    • Run a while loop until ‘i<=N’ and ‘j<SIZE’
      • Initialize the variable named ‘X’ with the number value of character ‘ARR[index][j]’.
      • If ‘DP[i][X] <= N’
        • Increment ‘j’ by ‘1’.
      • Assign ‘i’ the value of ‘DP[i][X]’.
    • If ‘j == SIZE’
      • Increment ‘ANS’ by ‘1’.
  • Return ‘ANS’.