Given two sequences A, B, find out number of unique ways in sequence A, to form a subsequence of A that is identical to sequence B. Transformation is meant by converting string A (by removing 0 or more characters) to string B.
Examples:
Input : A = "abcccdf", B = "abccdf"
Output : 3
Explanation : Three ways will be -> "ab.ccdf",
"abc.cdf" & "abcc.df" .
"." is where character is removed.
Input : A = "aabba", B = "ab"
Output : 4
Explanation : Four ways will be -> "a.b..",
"a..b.", ".ab.." & ".a.b." .
"." is where characters are removed.
Asked in : Google
The idea to solve this problem is using Dynamic Programming. Construct a 2D DP matrix of m*n size, where m is size of string B and n is size of string A.
dp[i][j] gives the number of ways of transforming string A[0…j] to B[0…i].
- Case 1 : dp[0][j] = 1, since placing B = “” with any substring of A would have only 1 solution which is to delete all characters in A.
- Case 2 : when i > 0, dp[i][j] can be derived by two cases:
- Case 2.a : if B[i] != A[j], then the solution would be to ignore the character A[j] and align substring B[0..i] with A[0..(j-1)]. Therefore, dp[i][j] = dp[i][j-1].
- Case 2.b : if B[i] == A[j], then first we could have the solution in case a), but also we could match the characters B[i] and A[j] and place the rest of them (i.e. B[0..(i-1)] and A[0..(j-1)]. As a result, dp[i][j] = dp[i][j-1] + dp[i-1][j-1].
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int countTransformation(string a, string b)
{
int n = a.size(), m = b.size();
if (m == 0)
return 1;
int dp[m][n];
memset (dp, 0, sizeof (dp));
for ( int i = 0; i < m; i++) {
for ( int j = i; j < n; j++) {
if (i == 0) {
if (j == 0)
dp[i][j] = (a[j] == b[i]) ? 1 : 0;
else if (a[j] == b[i])
dp[i][j] = dp[i][j - 1] + 1;
else
dp[i][j] = dp[i][j - 1];
}
else {
if (a[j] == b[i])
dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1];
else
dp[i][j] = dp[i][j - 1];
}
}
}
return dp[m - 1][n - 1];
}
int main()
{
string a = "abcccdf" , b = "abccdf" ;
cout << countTransformation(a, b) << endl;
return 0;
}
|
Java
import java.util.*;
import java.io.*;
class GFG {
static int countTransformation(String a,
String b)
{
int n = a.length(), m = b.length();
if (m == 0 ) {
return 1 ;
}
int dp[][] = new int [m][n];
for ( int i = 0 ; i < m; i++) {
for ( int j = i; j < n; j++) {
if (i == 0 ) {
if (j == 0 ) {
dp[i][j] = (a.charAt(j) == b.charAt(i)) ? 1 : 0 ;
}
else if (a.charAt(j) == b.charAt(i)) {
dp[i][j] = dp[i][j - 1 ] + 1 ;
}
else {
dp[i][j] = dp[i][j - 1 ];
}
}
else if (a.charAt(j) == b.charAt(i)) {
dp[i][j] = dp[i][j - 1 ]
+ dp[i - 1 ][j - 1 ];
}
else {
dp[i][j] = dp[i][j - 1 ];
}
}
}
return dp[m - 1 ][n - 1 ];
}
public static void main(String[] args)
{
String a = "abcccdf" , b = "abccdf" ;
System.out.println(countTransformation(a, b));
}
}
|
Python3
def countTransformation(a, b):
n = len (a)
m = len (b)
if m = = 0 :
return 1
dp = [[ 0 ] * (n) for _ in range (m)]
for i in range (m):
for j in range (i, n):
if i = = 0 :
if j = = 0 :
if a[j] = = b[i]:
dp[i][j] = 1
else :
dp[i][j] = 0
elif a[j] = = b[i]:
dp[i][j] = dp[i][j - 1 ] + 1
else :
dp[i][j] = dp[i][j - 1 ]
else :
if a[j] = = b[i]:
dp[i][j] = (dp[i][j - 1 ] +
dp[i - 1 ][j - 1 ])
else :
dp[i][j] = dp[i][j - 1 ]
return dp[m - 1 ][n - 1 ]
if __name__ = = "__main__" :
a = "abcccdf"
b = "abccdf"
print (countTransformation(a, b))
|
C#
using System;
class GFG {
static int countTransformation( string a, string b)
{
int n = a.Length, m = b.Length;
if (m == 0)
return 1;
int [, ] dp = new int [m, n];
for ( int i = 0; i < m; i++)
for ( int j = 0; j < n; j++)
dp[i, j] = 0;
for ( int i = 0; i < m; i++) {
for ( int j = i; j < n; j++) {
if (i == 0) {
if (j == 0)
dp[i, j] = (a[j] == b[i]) ? 1 : 0;
else if (a[j] == b[i])
dp[i, j] = dp[i, j - 1] + 1;
else
dp[i, j] = dp[i, j - 1];
}
else {
if (a[j] == b[i])
dp[i, j] = dp[i, j - 1] + dp[i - 1, j - 1];
else
dp[i, j] = dp[i, j - 1];
}
}
}
return dp[m - 1, n - 1];
}
static void Main()
{
string a = "abcccdf" , b = "abccdf" ;
Console.Write(countTransformation(a, b));
}
}
|
Javascript
<script>
function countTransformation(a,b)
{
var n = a.length, m = b.length;
if (m == 0) {
return 1;
}
var dp = new Array (m,n);
for ( var i = 0; i < m; i++) {
for ( var j = i; j < n; j++) {
if (i == 1) {
if (j == 1) {
dp[i,j] = (a[j] == b[i]) ? 1 : 0;
}
else if (a[j] == b[i]) {
dp[i,j] = dp[i,j - 1] + 1;
}
else {
dp[i,j] = dp[i,j - 1];
}
}
else if (a[j] == b[j]) {
dp[i,j] = dp[i,j - 1]
+ dp[i - 1,j - 1];
}
else {
dp[i,j] = dp[i,j - 1];
}
}
}
return dp[m - 1,n - 1];
}
var a = "abcccdf" , b = "abccdf" ;
document.write(countTransformation(a, b));
</script>
|
Time Complexity: O(m*n)
Auxiliary Space: O(m*n) because it is using extra space for array dp
If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
20 Dec, 2022
Like Article
Save Article