11. Shortest Common Supersequence
โ GFG solution to the Shortest Common Supersequence problem: find the length of smallest string containing both input strings as subsequences using dynamic programming. ๐
The problem can be found at the following link: ๐ Question Link
๐งฉ Problem Description
Given two strings s1 and s2, find the length of the smallest string which has both s1 and s2 as its subsequences.
A supersequence is a sequence that contains both strings as subsequences. The goal is to find the minimum length of such a supersequence where characters from both strings can be found in order (not necessarily contiguous).
Note: s1 and s2 can have both uppercase and lowercase English letters.
๐ Examples
Example 1
Input: s1 = "geek", s2 = "eke"
Output: 5
Explanation: String "geeke" has both string "geek" and "eke" as subsequences.Example 2
Input: s1 = "AGGTAB", s2 = "GXTXAYB"
Output: 9
Explanation: String "AGXGTXAYB" has both string "AGGTAB" and "GXTXAYB" as subsequences.Example 3
Input: s1 = "geek", s2 = "ek"
Output: 4
Explanation: String "geek" has both string "geek" and "ek" as subsequences.๐ Constraints
$1 \le \text{s1.size(), s2.size()} \le 500$
โ
My Approach
The optimal approach uses Space-Optimized Dynamic Programming to build the shortest common supersequence length:
Space-Optimized DP
Define DP State:
dp[i][j]represents the length of shortest common supersequence for firsticharacters ofs1and firstjcharacters ofs2.To optimize space, use only two 1D arrays:
prevandcurr.
Base Cases:
If
s1is empty (i = 0), we need all characters froms2, so length =j.If
s2is empty (j = 0), we need all characters froms1, so length =i.
State Transitions:
If characters match (
s1[i-1] == s2[j-1]): Include the character once.curr[j] = 1 + prev[j-1]
If characters don't match: Take minimum of two choices and add 1.
curr[j] = 1 + min(prev[j], curr[j-1])prev[j]means skip current character froms1curr[j-1]means skip current character froms2
Iterate Through Strings:
Process each character of both strings using nested loops.
Update
currarray based onprevarray values.After processing each row, copy
currtoprevfor next iteration.
Return Result:
Final answer is stored in
prev[n]after processing all characters.
๐ Time and Auxiliary Space Complexity
Expected Time Complexity: O(m ร n), where m is the length of string s1 and n is the length of string s2. We iterate through all possible combinations of characters from both strings using nested loops, performing constant-time operations for each cell.
Expected Auxiliary Space Complexity: O(n), where n is the length of string s2. We use two 1D arrays of size (n+1) to store previous and current row values, eliminating the need for a full 2D DP table and achieving space optimization.
๐งโ๐ป Code (C)
int minSuperSeq(char *s1, char *s2) {
int m = strlen(s1), n = strlen(s2);
int prev[n + 1], curr[n + 1];
for (int j = 0; j <= n; j++) prev[j] = j;
for (int i = 1; i <= m; i++) {
curr[0] = i;
for (int j = 1; j <= n; j++) {
curr[j] = (s1[i - 1] == s2[j - 1]) ? 1 + prev[j - 1] :
1 + (prev[j] < curr[j - 1] ? prev[j] : curr[j - 1]);
}
for (int j = 0; j <= n; j++) prev[j] = curr[j];
}
return prev[n];
}๐งโ๐ป Code (C++)
class Solution {
public:
int minSuperSeq(string &s1, string &s2) {
int m = s1.size(), n = s2.size();
vector<int> prev(n + 1), curr(n + 1);
for (int j = 0; j <= n; j++) prev[j] = j;
for (int i = 1; i <= m; i++) {
curr[0] = i;
for (int j = 1; j <= n; j++) {
curr[j] = (s1[i - 1] == s2[j - 1]) ? 1 + prev[j - 1] :
1 + min(prev[j], curr[j - 1]);
}
prev = curr;
}
return prev[n];
}
};โ Code (Java)
class Solution {
public static int minSuperSeq(String s1, String s2) {
int m = s1.length(), n = s2.length();
int[] prev = new int[n + 1], curr = new int[n + 1];
for (int j = 0; j <= n; j++) prev[j] = j;
for (int i = 1; i <= m; i++) {
curr[0] = i;
for (int j = 1; j <= n; j++) {
curr[j] = (s1.charAt(i - 1) == s2.charAt(j - 1)) ? 1 + prev[j - 1] :
1 + Math.min(prev[j], curr[j - 1]);
}
prev = curr.clone();
}
return prev[n];
}
}๐ Code (Python)
class Solution:
def minSuperSeq(self, s1, s2):
m, n = len(s1), len(s2)
prev, curr = [0] * (n + 1), [0] * (n + 1)
for j in range(n + 1): prev[j] = j
for i in range(1, m + 1):
curr[0] = i
for j in range(1, n + 1):
curr[j] = 1 + prev[j - 1] if s1[i - 1] == s2[j - 1] else 1 + min(prev[j], curr[j - 1])
prev = curr[:]
return prev[n]๐ง Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: ๐ฌ Any Questions?. Let's make this learning journey more collaborative!
โญ If you find this helpful, please give this repository a star! โญ
๐Visitor Count
Last updated