6. Longest Common Subsequence
The problem can be found at the following link: Question Link
Problem Description
Given two strings s1
and s2
, return the length of their longest common subsequence (LCS). If there is no common subsequence, return 0
.
A subsequence is a sequence that can be derived from the given string by deleting some or no elements without changing the order of the remaining elements. For example, "ABE"
is a subsequence of "ABCDE"
.
Examples
Example 1:
Input:
s1 = "ABCDGH", s2 = "AEDFHR"
Output:
3
Explanation:
The longest common subsequence of "ABCDGH"
and "AEDFHR"
is "ADH", which has a length of 3.
Example 2:
Input:
s1 = "ABC", s2 = "AC"
Output:
2
Explanation:
The longest common subsequence of "ABC"
and "AC"
is "AC", which has a length of 2.
Example 3:
Input:
s1 = "XYZW", s2 = "XYWZ"
Output:
3
Explanation:
The longest common subsequences of "XYZW"
and "XYWZ"
are "XYZ" and "XYW", both of length 3.
Constraints:
$(1 \leq \text{length}(s1), \text{length}(s2) \leq 10^3)$
Both
s1
ands2
contain only uppercase English letters.
My Approach
Space-Optimized 1D DP
Key Idea
Use only two arrays (current and previous rows) to store LCS lengths for substrings.
The value at
dp[j]
represents the LCS length ofs1[0..i-1]
ands2[0..j-1]
.Only the previous row is needed to compute the current row, so space is reduced to O(M), where M is the length of the second string.
Algorithm Steps
Use two rolling 1D arrays (or one array with a few variables) to store only the previous row and current row.
Traverse the strings from
i = 1..n
andj = 1..m
:If
s1[i - 1] == s2[j - 1]
, we docurr[j] = prev[j - 1] + 1
.Else,
curr[j] = max(prev[j], curr[j - 1])
.
Swap
prev
andcurr
at the end of eachi
iteration.The result is
prev[m]
, which is the length of LCS.
This approach is more space-efficient than the standard O(N * M)
DP table because it only keeps two rows (or one row with updates).
Time and Auxiliary Space Complexity
Expected Time Complexity:
O(N * M)
, whereN
is the length ofs1
andM
is the length ofs2
.Expected Auxiliary Space Complexity:
O(N)
, using the space-optimized approach (storing only one dimension).
Code (C++)
class Solution {
public:
int lcs(string &s1, string &s2) {
int n = s1.size(), m = s2.size();
vector<int> prev(m + 1, 0), curr(m + 1, 0);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
curr[j] = s1[i - 1] == s2[j - 1] ? prev[j - 1] + 1 : max(prev[j], curr[j - 1]);
}
swap(prev, curr);
}
return prev[m];
}
};
Code (Java)
class Solution {
static int lcs(String s1, String s2) {
int n = s1.length(), m = s2.length();
int[] prev = new int[m + 1], curr = new int[m + 1];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
curr[j] = s1.charAt(i - 1) == s2.charAt(j - 1) ? prev[j - 1] + 1 : Math.max(prev[j], curr[j - 1]);
}
int[] temp = prev; prev = curr; curr = temp;
}
return prev[m];
}
}
Code (Python)
class Solution:
def lcs(self, s1, s2):
m, n = len(s1), len(s2)
dp = [0] * (n + 1)
for i in range(m):
prev = 0
for j in range(n):
temp = dp[j + 1]
dp[j + 1] = prev + 1 if s1[i] == s2[j] else max(dp[j + 1], dp[j])
prev = temp
return dp[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