Given a string, count the number of times a given pattern appears in it as a subsequence.

Please note that the problem specifically targets subsequences that need not be contiguous, i.e., subsequences are not required to occupy consecutive positions within the original sequences.

 
For example,

Input:
 
string = “subsequence”
pattern = “sue”
 
Output: 7
 
subsequence
subsequence
subsequence
subsequence
subsequence
subsequence
subsequence

Practice this problem

The idea is to use recursion to solve this problem. If we compare the last character of the string X[0…m] with the last character of pattern Y[0…n], there are two possibilities:

  1. If the string’s last character is the same as the last character of the pattern, recur for the remaining substring X[0…m-1] and Y[0…n-1]. Since we want all possible combinations, also consider the case when the string’s current character does not form part of the solution, i.e., ignore the last character of the string and recur for the remaining substring X[0…m-1].
  2. If the last character of the string is different from the last character of the pattern, ignore the last character of the string and recur for the remaining substring X[0…m-1].

The algorithm can be implemented as follows in C++, Java, and Python:

C++


Download  Run Code

Output:

7

Java


Download  Run Code

Output:

7

Python


Download  Run Code

Output:

7

The time complexity of the above solution is exponential and occupies space in the call stack.
 

 
The idea is to use dynamic programming to solve this problem. The problem has an optimal substructure and exhibits overlapping subproblems. If we draw the recursion tree of the solution, we can see that the same subproblems are getting computed repeatedly.

We know that problems with optimal substructure and overlapping subproblems can be solved using dynamic programming, in which subproblem solutions are memoized rather than computed repeatedly. The memoized version follows the top-down approach since we first break the problem into subproblems and then calculate and store values. We can also solve this problem in a bottom-up manner. In the bottom-up approach, we solve smaller subproblems first, then solve larger subproblems from them.

 
The algorithm can be implemented as follows in C++, Java, and Python, where T[][] is filled in a bottom-up fashion.

C++


Download  Run Code

Output:

7

Java


Download  Run Code

Output:

7

Python


Download  Run Code

Output:

7

The time complexity of the above solution is O(m.n) and requires O(m.n) extra space, where m is the length of the first string and n is the length of the second string.