The Longest Common Subsequence (LCS) problem is a classic challenge that often appears in programming interviews, particularly in advanced dynamic programming contexts. Understanding LCS is crucial for tackling various string manipulation problems efficiently. Here, we will break down the problem, explore its properties, and look into dynamic programming solutions, all while providing illustrative examples.
The Longest Common Subsequence of two sequences is defined as the longest sequence that can be derived from both input sequences by deleting some elements without changing the order of the remaining elements. The LCS is not restricted to being contiguous in the original sequences, which makes it a more complex problem than finding the longest common substring.
Consider the two sequences:
AGGTAB
GXTXAYB
The longest common subsequence in these two sequences is GTAB
, which has a length of 4.
Create a 2D Array: A 2D array dp
is constructed where dp[i][j]
will hold the length of LCS of the prefixes A[0..i-1]
and B[0..j-1]
.
Initialization: Start by initializing the first row and the first column of the dp
table to 0
, since the LCS of any sequence with an empty sequence is 0
.
Filling the DP Table:
Reconstruction of the LCS: After filling up the dp
table, the length of the LCS will be found in dp[m][n]
, where m
and n
are the lengths of sequences A and B, respectively. To find the actual LCS, backtrack through the table.
Here's how you can implement the above logic in Python:
def longest_common_subsequence(A, B): m, n = len(A), len(B) dp = [[0] * (n + 1) for _ in range(m + 1)] # Fill the dp array for i in range(1, m + 1): for j in range(1, n + 1): if A[i - 1] == B[j - 1]: dp[i][j] = dp[i - 1][j - 1] + 1 else: dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) # Reconstruct the LCS lcs_length = dp[m][n] lcs = [] while m > 0 and n > 0: if A[m - 1] == B[n - 1]: lcs.append(A[m - 1]) m -= 1 n -= 1 elif dp[m - 1][n] > dp[m][n - 1]: m -= 1 else: n -= 1 return lcs_length, ''.join(reversed(lcs)) # Example usage A = "AGGTAB" B = "GXTXAYB" length, sequence = longest_common_subsequence(A, B) print(f"LCS Length: {length}, LCS: '{sequence}'")
In this implementation, we construct a dp
table and run through the sequences. After building the table, we can backtrack to find the actual sequence as well.
The time complexity of the LCS problem is (O(m \times n)), where (m) and (n) are the lengths of the input sequences. The space complexity is also (O(m \times n)) due to the dp
table. However, with optimization, we can reduce the space complexity to (O(\min(m, n))) by using just two rows of the table.
Understanding the Longest Common Subsequence not only sharpens algorithmic skills but also enhances problem-solving techniques that apply broadly across various domains in computer science and software engineering.
13/10/2024 | DSA
06/12/2024 | DSA
23/09/2024 | DSA
16/11/2024 | DSA
23/09/2024 | DSA
06/12/2024 | DSA
06/12/2024 | DSA
23/09/2024 | DSA
13/10/2024 | DSA
06/12/2024 | DSA
15/11/2024 | DSA
15/11/2024 | DSA