04. LCS of three Strings
โ GFG solution for LCS of 3 strings: dynamic programming with full 3D table, space optimized 2D, and recursion with memoization. ๐ก
The problem can be found at the following link: ๐ Question Link
๐งฉ Problem Description
Given three strings A
, B
, and C
, the task is to find the length of the Longest Common Subsequence (LCS) present in all three strings.
A subsequence is a sequence that appears in the same relative order, but not necessarily contiguous.
๐ Examples
Example 1
Input:
s1 = "geeks"
s2 = "geeksfor"
s3 = "geeksforgeeks"
Output: 5
Explanation:
The longest common subsequence is "geeks" (length = 5).
Example 2
Input:
s1 = "abcd1e2"
s2 = "bc12ea"
s3 = "bd1ea"
Output: 3
Explanation:
The longest common subsequence is "b1e" (length = 3).
๐ Constraints
$1 \leq |s1|,|s2|,|s3| \leq 100$
Strings contain only lowercase English letters.
โ
My Approach
Optimized 2D DP (Rolling Arrays)
Idea:
A naive 3D DP table $dp[i][j][k]$ (size $(n1+1) \times (n2+1) \times (n3+1)$) takes $O(n1 \times n2 \times n3)$ time and space.
We can reduce space by noticing that at layer
i
, we only need layeri-1
to compute the current values.Maintain two 2D arrays
prev[j][k]
andcurr[j][k]
of size $(n2+1) \times (n3+1)$.
DP Relation:
Let
n1 = |s1|
,n2 = |s2|
,n3 = |s3|
.For each
i
from1
ton1
, and for eachj
from1
ton2
, and eachk
from1
ton3
:If
s1[i-1] == s2[j-1] == s3[k-1]
, thenOtherwise,
After filling
curr
for a fixedi
, swapprev
andcurr
, and zero outcurr
for the next iteration.
Answer:
The value
prev[n2][n3]
at the end of the loops is the length of the LCS among all three strings.
๐ Time and Auxiliary Space Complexity
Expected Time Complexity: $\displaystyle O(n1 \times n2 \times n3)$, since we iterate over all
i โ [1..n1]
,j โ [1..n2]
,k โ [1..n3]
.Expected Auxiliary Space Complexity: $\displaystyle O(n2 \times n3)$, because we only store two 2D arrays of size $(n2+1)\times(n3+1)$ instead of a full 3D table.
๐งโ๐ป Code (C++)
class Solution {
public:
int lcsOf3(string& s1, string& s2, string& s3) {
int n1 = s1.length(), n2 = s2.length(), n3 = s3.length();
vector<vector<int>> prev(n2 + 1, vector<int>(n3 + 1, 0));
vector<vector<int>> curr(n2 + 1, vector<int>(n3 + 1, 0));
for (int i = 1; i <= n1; ++i) {
for (int j = 1; j <= n2; ++j) {
for (int k = 1; k <= n3; ++k) {
if (s1[i - 1] == s2[j - 1] && s2[j - 1] == s3[k - 1])
curr[j][k] = 1 + prev[j - 1][k - 1];
else
curr[j][k] = max({prev[j][k], curr[j - 1][k], curr[j][k - 1]});
}
}
prev.swap(curr);
}
return prev[n2][n3];
}
};
๐งโ๐ป Code (Java)
class Solution {
int lcsOf3(String s1, String s2, String s3) {
int n1 = s1.length(), n2 = s2.length(), n3 = s3.length();
int[][] prev = new int[n2 + 1][n3 + 1];
int[][] curr = new int[n2 + 1][n3 + 1];
for (int i = 1; i <= n1; ++i) {
for (int j = 1; j <= n2; ++j) {
for (int k = 1; k <= n3; ++k) {
if (s1.charAt(i - 1) == s2.charAt(j - 1) &&
s2.charAt(j - 1) == s3.charAt(k - 1))
curr[j][k] = 1 + prev[j - 1][k - 1];
else
curr[j][k] = Math.max(
Math.max(prev[j][k], curr[j - 1][k]),
curr[j][k - 1]
);
}
}
int[][] temp = prev;
prev = curr;
curr = temp;
}
return prev[n2][n3];
}
}
๐ Code (Python)
class Solution:
def lcsOf3(self, s1, s2, s3):
n1, n2, n3 = len(s1), len(s2), len(s3)
prev = [[0] * (n3 + 1) for _ in range(n2 + 1)]
curr = [[0] * (n3 + 1) for _ in range(n2 + 1)]
for i in range(1, n1 + 1):
for j in range(1, n2 + 1):
for k in range(1, n3 + 1):
if s1[i - 1] == s2[j - 1] == s3[k - 1]:
curr[j][k] = 1 + prev[j - 1][k - 1]
else:
curr[j][k] = max(
prev[j][k],
curr[j - 1][k],
curr[j][k - 1]
)
prev, curr = curr, prev
return prev[n2][n3]
๐ง 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