Printing Longest Common Subsequence
Given two sequences, print the longest subsequence present in both of them.
- LCS for input Sequences “ABCDGH” and “AEDFHR” is “ADH” of length 3.
- LCS for input Sequences “AGGTAB” and “GXTXAYB” is “GTAB” of length 4.
We have discussed Longest Common Subsequence (LCS) problem in a previous post. The function discussed there was mainly to find the length of LCS. To find length of LCS, a 2D table L was constructed. In this post, the function to construct and print LCS is discussed.
Following is detailed algorithm to print the LCS. It uses the same 2D table L.
- Construct L[m+1][n+1] using the steps discussed in previous post.
- The value L[m][n] contains length of LCS. Create a character array lcs of length equal to the length of lcs plus 1 (one extra to store \0).
- Traverse the 2D array starting from L[m][n]. Do following for every cell L[i][j]
- If characters (in X and Y) corresponding to L[i][j] are same (Or X[i-1] == Y[j-1]), then include this character as part of LCS.
- Else compare values of L[i-1][j] and L[i][j-1] and go in direction of greater value.
The following table (taken from Wiki) shows steps (highlighted) followed by the above algorithm.
Following is the implementation of the above approach.
LCS of AGGTAB and GXTXAYB is GTAB
Time Complexity: O(m*n)
Auxiliary Space: O(m*n)
Top-down approach for printing Longest Common Subsequence:
Follow the steps below for the implementation:
- Check if one of the two strings is of size zero, then we return an empty string because the LCS, in this case, is empty (base case).
- Check if not the base case, then if we have a solution for the current a and b saved in the memory, we return it, else we calculate the solution for the current a and b and store it in memory.
- For calculation of solution, we compare the last two characters of a and b.
- Check if they are equal,
- If true, we add this character to the solution string, then we erase the last character from each string and add to the solution string the string returned from LCS(a, b) after deleting the last characters.
- Otherwise, if the last two characters don’t equal each other, we call LCS(a_without_last_character, b) and LCS(a, b_without_last_character). Then we compare the two returned strings and add the bigger string to the solution string.
- Store the solution in the memory and return it.
- Reverse the final returned solution, given that our top-down approach generates a reversed string.
Here is the implementation of the above recursive approach.
Time complexity: O(m*n) where m is the length of the first string and n is the length of the second string. This is because, for each character in both strings, we need to check whether they are equal and then recursively call the LCS_core() function.
Auxiliary space: O(m*n) as well. This is because we are using a map structure to keep track of the visited subproblems and the result of each subproblem. This structure is having a size of O(m*n).