Given two strings, str1
and str2
, find the shortest string that contains both str1
and str2
as subsequences.
Definition: A string S is a subsequence of another string T if you can remove some characters from T (without changing the order of the remaining characters) to get S.
Input:
str1 = "abac"
str2 = "cab"
Output:
"cabac"
Explanation:
"abac"
is a subsequence of "cabac"
(for example, remove the first "c"
)."cab"
is also a subsequence of "cabac"
(for example, remove the last "ac"
).Input:
str1 = "aaaaaaaa"
str2 = "aaaaaaaa"
Output:
"aaaaaaaa"
Explanation:
Both strings are identical; therefore, the SCS is the same as each string.
Input:
str1 = "geek"
str2 = "eke"
Possible Output:
"geeke"
Explanation:
"geek"
is a subsequence of "geeke"
(remove the extra "e"
in the middle)."eke"
is also a subsequence of "geeke"
.Input:
str1 = "AGGTAB"
str2 = "GXTXAYB"
Possible Output:
"AGGXTXAYB"
Explanation:
The output "AGXGTXAYB"
is one valid SCS that contains both "AGGTAB"
and "GXTXAYB"
as subsequences.
len(str1) + len(str2) - len(LCS(str1, str2))
The DP array (or table) plays a crucial role in solving the Shortest Common Supersequence (SCS) problem by first helping us compute the Longest Common Subsequence (LCS) of the two input strings.
dp
with dimensions (m+1) x (n+1)
, where m
and n
are the
lengths of the two strings.dp[i][j]
stores the length of the LCS between the first i
characters of str1
and the
first
j
characters of str2
.str1[i-1] == str2[j-1]
, then dp[i][j] = dp[i-1][j-1] + 1
.dp[i][j] = max(dp[i-1][j], dp[i][j-1])
.len(SCS) = len(str1) + len(str2) - len(LCS)
shows that the more characters the strings share (in order), the shorter the SCS can be.dp[m][n]
to reconstruct the SCS.str1[i-1]
and str2[j-1]
are the same, that character is part of the LCS, so we include it in the SCS and move diagonally (i.e., i--, j--
).dp[i-1][j]
and dp[i][j-1]
:
The DP array is useful because it:
In essence, the DP array is the backbone of the solution—it not only provides the length of the LCS (which directly relates to the minimum SCS length) but also guides the process of merging the two strings into one minimal supersequence.
Feel free to use these examples to test and understand your solution!
https://leetcode.com/problems/shortest-common-supersequence/description/
Loading component...
Loading component...
Main Function is not defined.
INPUT: str1 = "AGGTAB" str2 = "GXTXAYB"
Output: "AGGXTXAYB"
public String shortestCommonSupersequence1(String str1, String str2) {
int m = str1.length(), n = str2.length();
int[][] dp = new int[m+1][n+1];
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (str1.charAt(i-1) == str2.charAt(j-1)) {
dp[i][j] = dp[i-1][j-1] + 1;
}//If End
else {
dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
}//Else End
}//Loop End
}//Loop End
StringBuilder sb = new StringBuilder();
int i = m, j = n;
while (i > 0 && j > 0) {
if (str1.charAt(i-1) == str2.charAt(j-1)) {
sb.append(str1.charAt(i-1));
i--;
j--;
}//If End
else{
if (dp[i-1][j] > dp[i][j-1]) {
sb.append(str1.charAt(i-1));
i--;
}//If End
else {
sb.append(str2.charAt(j-1));
j--;
}//Else End
}//Else End
}//Loop End
while (i > 0) {
sb.append(str1.charAt(i-1));
i--;
}//Loop End
while (j > 0) {
sb.append(str2.charAt(j-1));
j--;
}//Loop End
return sb.reverse().toString();
}//function end
Utility Function is not required.