The problem of finding the shortest common supersequence (SCS) of two strings can be solved using dynamic programming. An SCS of two strings A and B is a string that contains both A and B as subsequences, and has the minimum possible length.
Let’s define a function S(i,j) as the length of the SCS of the substrings A[0:i] and B[0:j]. Using this definition, we can recursively define the value of S(i,j) using the following recurrence relation:
S(i,j) = 0, if i=0 or j=0 (i.e. if one of the strings is empty, their SCS is the other string)
S(i,j) = S(i-1, j-1) + 1, if A[i-1] = B[j-1] (i.e. if the last characters of A and B are the same, we can add that character to the SCS)
S(i,j) = min(S(i-1, j), S(i, j-1)) + 1, otherwise (i.e. if the last characters of A and B are different, we need to choose between the two options: add the last character of A or add the last character of B)
The base case of the recurrence is when one or both strings are empty, in which case their SCS is simply the other string. Otherwise, we handle two cases: either the last characters of A and B are the same, in which case we can add that character to the SCS, or they are different, in which case we have to choose which string to add to the SCS. The optimal choice is the one that leads to the shortest SCS.
We can apply this recurrence relation to compute S(n,m), where n and m are the lengths of strings A and B, respectively. The value of S(n,m) gives us the length of the SCS of A and B. However, it doesn’t give us the actual SCS. To obtain the SCS, we can use the following algorithm:
1. Initialize i=n and j=m.
2. Initialize an empty string result.
3. While i>0 and j>0, do the following:
* If A[i-1]=B[j-1], add A[i-1] (or B[j-1], it doesn't matter) to the beginning of the result, and decrement both i and j.
* Otherwise, compare S(i-1, j) and S(i, j-1). If S(i-1, j) is smaller, add A[i-1] to the beginning of the result and decrement i; otherwise add B[j-1] to the beginning of the result and decrement j.
4. Add the remaining characters of A or B, whichever is not empty, to the beginning of the result.
5. Reverse the result to get the actual SCS.
Here’s the Java code that implements the above algorithm:
public static String shortestCommonSupersequence(String A, String B) {
int n = A.length();
int m = B.length();
int[][] S = new int[n+1][m+1];
// Initialize base cases
for (int i=0; i<=n; i++) S[i][0] = 0;
for (int j=0; j<=m; j++) S[0][j] = 0;
// Compute S(i,j) using the recurrence
for (int i=1; i<=n; i++) {
for (int j=1; j<=m; j++) {
if (A.charAt(i-1)==B.charAt(j-1)) {
S[i][j] = S[i-1][j-1] + 1;
} else {
S[i][j] = Math.min(S[i-1][j], S[i][j-1]) + 1;
}
}
}
// Reconstruct the SCS from S
int i=n, j=m;
StringBuilder sb = new StringBuilder();
while (i>0 && j>0) {
if (A.charAt(i-1)==B.charAt(j-1)) {
sb.append(A.charAt(i-1));
i--;
j--;
} else {
if (S[i-1][j] < S[i][j-1]) {
sb.append(A.charAt(i-1));
i--;
} else {
sb.append(B.charAt(j-1));
j--;
}
}
}
while (i>0) {
sb.append(A.charAt(i-1));
i--;
}
while (j>0) {
sb.append(B.charAt(j-1));
j--;
}
return sb.reverse().toString();
}
The time complexity of this dynamic programming solution is O(nm), where n and m are the lengths of strings A and B, respectively. This is because we need to compute S(i,j) for all i in 0,1,...,n and all j in 0,1,...,m, which takes O(nm) time. The space complexity is also O(nm), because we need to store the entire S array.