Welcome to the daily solutions of our PROBLEM OF THE DAY (POTD). We will discuss the entire problem step-by-step and work towards developing an optimized solution. This will not only help you brush up on your concepts of Dynamic Programming but will also help you build up problem-solving skills.

POTD 13 November: Shortest Common Supersequence
Given two strings X and Y of lengths m and n respectively, find the length of the smallest string that has both, X and Y as its sub-sequences.
Note: X and Y can have both uppercase and lowercase letters.
Examples:
Input: X = "abcd", Y = "xycd"
Output: 6
Explanation: Shortest Common Supersequence would be abxycd which is of length 6 and has both the strings as its subsequences.Input: X = "efgh", Y = "jghi"
Output: 6
Explanation: Shortest Common Supersequence would be ejfghi which is of length 6 and has both the strings as its subsequences.
Shortest Common Supersequence using Dynamic Programming:
We need to find a string that has both strings as subsequences and is the shortest such string. If both strings have all characters different, then result is sum of lengths of two given strings. If there are common characters, then we don’t want them multiple times as the task is to minimize length. Therefore, we first find the longest common subsequence, take one occurrence of this subsequence and add extra characters.
Length of the shortest supersequence = (Sum of lengths of given two strings) - (Length of LCS of two given strings)
Below is the implementation of the above approach:
class Solution {
public:
// Returns length of LCS
// for X[0..m - 1], Y[0..n - 1]
int lcs(string& X, string& Y, int m, int n)
{
int L[m + 1][n + 1];
int i, j;
// Following steps build L[m + 1][n + 1]
// in bottom up fashion. Note that
// L[i][j] contains length of LCS of
// X[0..i - 1] and Y[0..j - 1]
for (i = 0; i <= m; i++) {
for (j = 0; j <= n; j++) {
if (i == 0 || j == 0)
L[i][j] = 0;
else if (X[i - 1] == Y[j - 1])
L[i][j] = L[i - 1][j - 1] + 1;
else
L[i][j] = max(L[i - 1][j], L[i][j - 1]);
}
}
// L[m][n] contains length of LCS
// for X[0..n - 1] and Y[0..m - 1]
return L[m][n];
}
// Function to find length of shortest common
// supersequence of two strings.
int shortestCommonSupersequence(string X, string Y,
int m, int n)
{
// find lcs
int l = lcs(X, Y, m, n);
// Result is sum of input string
// lengths - length of lcs
return (m + n - l);
}
};
class Solution {
// Returns length of LCS
// for X[0..m - 1], Y[0..n - 1]
static int lcs(String X, String Y, int m, int n)
{
int[][] L = new int[m + 1][n + 1];
int i, j;
// Following steps build L[m + 1][n + 1]
// in bottom up fashion. Note that
// L[i][j] contains length of LCS
// of X[0..i - 1]and Y[0..j - 1]
for (i = 0; i <= m; i++) {
for (j = 0; j <= n; j++) {
if (i == 0 || j == 0)
L[i][j] = 0;
else if (X.charAt(i - 1) == Y.charAt(j - 1))
L[i][j] = L[i - 1][j - 1] + 1;
else
L[i][j] = Math.max(L[i - 1][j],
L[i][j - 1]);
}
}
// L[m][n] contains length of LCS
// for X[0..n - 1] and Y[0..m - 1]
return L[m][n];
}
// Function to find length of shortest common
// supersequence of two strings.
public static int shortestCommonSupersequence(String X,
String Y,
int m,
int n)
{
// find lcs
int l = lcs(X, Y, m, n);
// Result is sum of input string
// lengths - length of lcs
return (m + n - l);
}
}
def lcs(X, Y, m, n):
L = [[0] * (n + 2) for i in
range(m + 2)]
# Following steps build L[m + 1][n + 1]
# in bottom up fashion. Note that L[i][j]
# contains length of LCS of X[0..i - 1]
# and Y[0..j - 1]
for i in range(m + 1):
for j in range(n + 1):
if (i == 0 or j == 0):
L[i][j] = 0
elif (X[i - 1] == Y[j - 1]):
L[i][j] = L[i - 1][j - 1] + 1
else:
L[i][j] = max(L[i - 1][j],
L[i][j - 1])
# L[m][n] contains length of
# LCS for X[0..n - 1] and Y[0..m - 1]
return L[m][n]
class Solution {
// Returns length of LCS for
// X[0..m - 1], Y[0..n - 1]
static int lcs(String X, String Y, int m, int n)
{
int[, ] L = new int[m + 1, n + 1];
int i, j;
// Following steps build L[m + 1][n + 1]
// in bottom up fashion.Note that
// L[i][j] contains length of LCS of
// X[0..i - 1] and Y[0..j - 1]
for (i = 0; i <= m; i++) {
for (j = 0; j <= n; j++) {
if (i == 0 || j == 0)
L[i, j] = 0;
else if (X[i - 1] == Y[j - 1])
L[i, j] = L[i - 1, j - 1] + 1;
else
L[i, j] = Math.Max(L[i - 1, j],
L[i, j - 1]);
}
}
// L[m][n] contains length of LCS
// for X[0..n - 1] and Y[0..m - 1]
return L[m, n];
}
// Complete this function
public int shortestCommonSupersequence(string x,
string y, int m,
int n)
{
// Your code here
// find lcs
int l = lcs(x, y, m, n);
// Result is sum of input string
// lengths - length of lcs
return (m + n - l);
}
}
class Solution
{
//Function to find length of shortest common supersequence of two strings.
shortestCommonSupersequence(X, Y, m, n)
{
// code here
let dp = new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(0));
// Fill the table using bottom-up dynamic programming
for (let i = 0; i <= m; i++) {
for (let j = 0; j <= n; j++) {
if (i === 0)
dp[i][j] = j;
else if (j === 0)
dp[i][j] = i;
else if (X[i - 1] === Y[j - 1])
dp[i][j] = 1 + dp[i - 1][j - 1];
else
dp[i][j] = 1 + Math.min(dp[i - 1][j], dp[i][j - 1]);
}
}
// The length of the shortest common supersequence is given by the bottom-right cell of the table
return dp[m][n];
}
}
Time Complexity: O(|X| * |Y|), where |X| is the length of string X and |Y| is the length of string Y.
Auxiliary Space: O(|X| * |Y|)