# Printing Longest Common Subsequence

Given two sequences, print the longest subsequence present in both of them.

**Examples:**

- 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.

0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | ||
---|---|---|---|---|---|---|---|---|---|

Ø | M | Z | J | A | W | X | U | ||

0 | Ø | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |

1 | X | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |

2 | M | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |

3 | J | 0 | 1 | 1 | 2 | 2 | 2 | 2 | 2 |

4 | Y | 0 | 1 | 1 | 2 | 2 | 2 | 2 | 2 |

5 | A | 0 | 1 | 1 | 2 | 3 | 3 | 3 | 3 |

6 | U | 0 | 1 | 1 | 2 | 3 | 3 | 3 | 4 |

7 | Z | 0 | 1 | 2 | 2 | 3 | 3 | 3 | 4 |

Following is the implementation of above approach.

## C++14

`/* Dynamic Programming implementation of LCS problem */` `#include <cstdlib>` `#include <cstring>` `#include <iostream>` `using` `namespace` `std;` `/* Returns length of LCS for X[0..m-1], Y[0..n-1] */` `void` `lcs(` `char` `* X, ` `char` `* Y, ` `int` `m, ` `int` `n)` `{` ` ` `int` `L[m + 1][n + 1];` ` ` `/* Following steps build L[m+1][n+1] in bottom up` ` ` `fashion. Note that L[i][j] contains length of LCS of` ` ` `X[0..i-1] and Y[0..j-1] */` ` ` `for` `(` `int` `i = 0; i <= m; i++) {` ` ` `for` `(` `int` `j = 0; j <= n; j++) {` ` ` `if` `(i == 0 || j == 0)` ` ` `L[i][j] = 0;` ` ` `else` `if` `(X[i - 1] == Y[j - 1])` ` ` `L[i][j] = L[i - 1][j - 1] + 1;` ` ` `else` ` ` `L[i][j] = max(L[i - 1][j], L[i][j - 1]);` ` ` `}` ` ` `}` ` ` `// Following code is used to print LCS` ` ` `int` `index = L[m][n];` ` ` `// Create a character array to store the lcs string` ` ` `char` `lcs[index + 1];` ` ` `lcs[index] = ` `'\0'` `; ` `// Set the terminating character` ` ` `// Start from the right-most-bottom-most corner and` ` ` `// one by one store characters in lcs[]` ` ` `int` `i = m, j = n;` ` ` `while` `(i > 0 && j > 0) {` ` ` `// If current character in X[] and Y are same, then` ` ` `// current character is part of LCS` ` ` `if` `(X[i - 1] == Y[j - 1]) {` ` ` `lcs[index - 1]` ` ` `= X[i - 1]; ` `// Put current character in result` ` ` `i--;` ` ` `j--;` ` ` `index--; ` `// reduce values of i, j and index` ` ` `}` ` ` `// If not same, then find the larger of two and` ` ` `// go in the direction of larger value` ` ` `else` `if` `(L[i - 1][j] > L[i][j - 1])` ` ` `i--;` ` ` `else` ` ` `j--;` ` ` `}` ` ` `// Print the lcs` ` ` `cout << ` `"LCS of "` `<< X << ` `" and "` `<< Y << ` `" is "` `<< lcs;` `}` `/* Driver program to test above function */` `int` `main()` `{` ` ` `char` `X[] = ` `"AGGTAB"` `;` ` ` `char` `Y[] = ` `"GXTXAYB"` `;` ` ` `int` `m = ` `strlen` `(X);` ` ` `int` `n = ` `strlen` `(Y);` ` ` `lcs(X, Y, m, n);` ` ` `return` `0;` `}` |

## Java

`// Dynamic Programming implementation of LCS problem in Java` `import` `java.io.*;` `class` `LongestCommonSubsequence {` ` ` `// Returns length of LCS for X[0..m-1], Y[0..n-1]` ` ` `static` `void` `lcs(String X, String Y, ` `int` `m, ` `int` `n)` ` ` `{` ` ` `int` `[][] L = ` `new` `int` `[m + ` `1` `][n + ` `1` `];` ` ` `// Following steps build L[m+1][n+1] in bottom up` ` ` `// fashion. Note that L[i][j] contains length of LCS` ` ` `// of X[0..i-1] and Y[0..j-1]` ` ` `for` `(` `int` `i = ` `0` `; i <= m; i++) {` ` ` `for` `(` `int` `j = ` `0` `; j <= n; j++) {` ` ` `if` `(i == ` `0` `|| j == ` `0` `)` ` ` `L[i][j] = ` `0` `;` ` ` `else` `if` `(X.charAt(i - ` `1` `) == Y.charAt(j - ` `1` `))` ` ` `L[i][j] = L[i - ` `1` `][j - ` `1` `] + ` `1` `;` ` ` `else` ` ` `L[i][j] = Math.max(L[i - ` `1` `][j],` ` ` `L[i][j - ` `1` `]);` ` ` `}` ` ` `}` ` ` `// Following code is used to print LCS` ` ` `int` `index = L[m][n];` ` ` `int` `temp = index;` ` ` `// Create a character array to store the lcs string` ` ` `char` `[] lcs = ` `new` `char` `[index + ` `1` `];` ` ` `lcs[index]` ` ` `= ` `'\u0000'` `; ` `// Set the terminating character` ` ` `// Start from the right-most-bottom-most corner and` ` ` `// one by one store characters in lcs[]` ` ` `int` `i = m;` ` ` `int` `j = n;` ` ` `while` `(i > ` `0` `&& j > ` `0` `) {` ` ` `// If current character in X[] and Y are same,` ` ` `// then current character is part of LCS` ` ` `if` `(X.charAt(i - ` `1` `) == Y.charAt(j - ` `1` `)) {` ` ` `// Put current character in result` ` ` `lcs[index - ` `1` `] = X.charAt(i - ` `1` `);` ` ` `// reduce values of i, j and index` ` ` `i--;` ` ` `j--;` ` ` `index--;` ` ` `}` ` ` `// If not same, then find the larger of two and` ` ` `// go in the direction of larger value` ` ` `else` `if` `(L[i - ` `1` `][j] > L[i][j - ` `1` `])` ` ` `i--;` ` ` `else` ` ` `j--;` ` ` `}` ` ` `// Print the lcs` ` ` `System.out.print(` `"LCS of "` `+ X + ` `" and "` `+ Y` ` ` `+ ` `" is "` `);` ` ` `for` `(` `int` `k = ` `0` `; k <= temp; k++)` ` ` `System.out.print(lcs[k]);` ` ` `}` ` ` `// driver program` ` ` `public` `static` `void` `main(String[] args)` ` ` `{` ` ` `String X = ` `"AGGTAB"` `;` ` ` `String Y = ` `"GXTXAYB"` `;` ` ` `int` `m = X.length();` ` ` `int` `n = Y.length();` ` ` `lcs(X, Y, m, n);` ` ` `}` `}` `// Contributed by Pramod Kumar` |

## Python3

`# Dynamic programming implementation of LCS problem` `# Returns length of LCS for X[0..m-1], Y[0..n-1]` `def` `lcs(X, Y, m, n):` ` ` `L ` `=` `[[` `0` `for` `i ` `in` `range` `(n` `+` `1` `)] ` `for` `j ` `in` `range` `(m` `+` `1` `)]` ` ` `# Following steps build L[m+1][n+1] in bottom up fashion. Note` ` ` `# that L[i][j] contains length of LCS of X[0..i-1] and Y[0..j-1]` ` ` `for` `i ` `in` `range` `(m` `+` `1` `):` ` ` `for` `j ` `in` `range` `(n` `+` `1` `):` ` ` `if` `i ` `=` `=` `0` `or` `j ` `=` `=` `0` `:` ` ` `L[i][j] ` `=` `0` ` ` `elif` `X[i` `-` `1` `] ` `=` `=` `Y[j` `-` `1` `]:` ` ` `L[i][j] ` `=` `L[i` `-` `1` `][j` `-` `1` `] ` `+` `1` ` ` `else` `:` ` ` `L[i][j] ` `=` `max` `(L[i` `-` `1` `][j], L[i][j` `-` `1` `])` ` ` `# Create a string variable to store the lcs string` ` ` `lcs ` `=` `""` ` ` `# Start from the right-most-bottom-most corner and` ` ` `# one by one store characters in lcs[]` ` ` `i ` `=` `m` ` ` `j ` `=` `n` ` ` `while` `i > ` `0` `and` `j > ` `0` `:` ` ` `# If current character in X[] and Y are same, then` ` ` `# current character is part of LCS` ` ` `if` `X[i` `-` `1` `] ` `=` `=` `Y[j` `-` `1` `]:` ` ` `lcs ` `+` `=` `X[i` `-` `1` `]` ` ` `i ` `-` `=` `1` ` ` `j ` `-` `=` `1` ` ` `# If not same, then find the larger of two and` ` ` `# go in the direction of larger value` ` ` `elif` `L[i` `-` `1` `][j] > L[i][j` `-` `1` `]:` ` ` `i ` `-` `=` `1` ` ` ` ` `else` `:` ` ` `j ` `-` `=` `1` ` ` `# We traversed the table in reverse order` ` ` `# LCS is the reverse of what we got` ` ` `lcs ` `=` `lcs[::` `-` `1` `]` ` ` `print` `(` `"LCS of "` `+` `X ` `+` `" and "` `+` `Y ` `+` `" is "` `+` `lcs)` `# Driver program` `X ` `=` `"AGGTAB"` `Y ` `=` `"GXTXAYB"` `m ` `=` `len` `(X)` `n ` `=` `len` `(Y)` `lcs(X, Y, m, n)` `# This code is contributed by AMAN ASATI` |

## C#

`// Dynamic Programming implementation` `// of LCS problem in C#` `using` `System;` `class` `GFG {` ` ` `// Returns length of LCS for X[0..m-1], Y[0..n-1]` ` ` `static` `void` `lcs(String X, String Y, ` `int` `m, ` `int` `n)` ` ` `{` ` ` `int` `[, ] L = ` `new` `int` `[m + 1, n + 1];` ` ` `// Following steps build L[m+1][n+1] in` ` ` `// bottom up fashion. Note that L[i][j]` ` ` `// contains length of LCS of X[0..i-1]` ` ` `// and Y[0..j-1]` ` ` `for` `(` `int` `i = 0; i <= m; i++) {` ` ` `for` `(` `int` `j = 0; j <= n; j++) {` ` ` `if` `(i == 0 || j == 0)` ` ` `L[i, j] = 0;` ` ` `else` `if` `(X[i - 1] == Y[j - 1])` ` ` `L[i, j] = L[i - 1, j - 1] + 1;` ` ` `else` ` ` `L[i, j] = Math.Max(L[i - 1, j],` ` ` `L[i, j - 1]);` ` ` `}` ` ` `}` ` ` `// Following code is used to print LCS` ` ` `int` `index = L[m, n];` ` ` `int` `temp = index;` ` ` `// Create a character array` ` ` `// to store the lcs string` ` ` `char` `[] lcs = ` `new` `char` `[index + 1];` ` ` `// Set the terminating character` ` ` `lcs[index] = ` `'\0'` `;` ` ` `// Start from the right-most-bottom-most corner` ` ` `// and one by one store characters in lcs[]` ` ` `int` `k = m, l = n;` ` ` `while` `(k > 0 && l > 0) {` ` ` `// If current character in X[] and Y` ` ` `// are same, then current character` ` ` `// is part of LCS` ` ` `if` `(X[k - 1] == Y[l - 1]) {` ` ` `// Put current character in result` ` ` `lcs[index - 1] = X[k - 1];` ` ` `// reduce values of i, j and index` ` ` `k--;` ` ` `l--;` ` ` `index--;` ` ` `}` ` ` `// If not same, then find the larger of two and` ` ` `// go in the direction of larger value` ` ` `else` `if` `(L[k - 1, l] > L[k, l - 1])` ` ` `k--;` ` ` `else` ` ` `l--;` ` ` `}` ` ` `// Print the lcs` ` ` `Console.Write(` `"LCS of "` `+ X + ` `" and "` `+ Y + ` `" is "` `);` ` ` `for` `(` `int` `q = 0; q <= temp; q++)` ` ` `Console.Write(lcs[q]);` ` ` `}` ` ` `// Driver program` ` ` `public` `static` `void` `Main()` ` ` `{` ` ` `String X = ` `"AGGTAB"` `;` ` ` `String Y = ` `"GXTXAYB"` `;` ` ` `int` `m = X.Length;` ` ` `int` `n = Y.Length;` ` ` `lcs(X, Y, m, n);` ` ` `}` `}` `// This code is contributed by Sam007` |

## PHP

`<?php` `// Dynamic Programming implementation of LCS problem` `// Returns length of LCS for X[0..m-1], Y[0..n-1]` `function` `lcs( ` `$X` `, ` `$Y` `, ` `$m` `, ` `$n` `)` `{` ` ` `$L` `= ` `array_fill` `(0, ` `$m` `+ 1,` ` ` `array_fill` `(0, ` `$n` `+ 1, NULL));` ` ` ` ` `/* Following steps build L[m+1][n+1] in bottom` ` ` `up fashion. Note that L[i][j] contains length` ` ` `of LCS of X[0..i-1] and Y[0..j-1] */` ` ` `for` `(` `$i` `= 0; ` `$i` `<= ` `$m` `; ` `$i` `++)` ` ` `{` ` ` `for` `(` `$j` `= 0; ` `$j` `<= ` `$n` `; ` `$j` `++)` ` ` `{` ` ` `if` `(` `$i` `== 0 || ` `$j` `== 0)` ` ` `$L` `[` `$i` `][` `$j` `] = 0;` ` ` `else` `if` `(` `$X` `[` `$i` `- 1] == ` `$Y` `[` `$j` `- 1])` ` ` `$L` `[` `$i` `][` `$j` `] = ` `$L` `[` `$i` `- 1][` `$j` `- 1] + 1;` ` ` `else` ` ` `$L` `[` `$i` `][` `$j` `] = max(` `$L` `[` `$i` `- 1][` `$j` `],` ` ` `$L` `[` `$i` `][` `$j` `- 1]);` ` ` `}` ` ` `}` ` ` ` ` `// Following code is used to print LCS` ` ` `$index` `= ` `$L` `[` `$m` `][` `$n` `];` ` ` `$temp` `= ` `$index` `;` ` ` ` ` `// Create a character array to store the lcs string` ` ` `$lcs` `= ` `array_fill` `(0, ` `$index` `+ 1, NULL);` ` ` `$lcs` `[` `$index` `] = ` `''` `; ` `// Set the terminating character` ` ` ` ` `// Start from the right-most-bottom-most corner` ` ` `// and one by one store characters in lcs[]` ` ` `$i` `= ` `$m` `;` ` ` `$j` `= ` `$n` `;` ` ` `while` `(` `$i` `> 0 && ` `$j` `> 0)` ` ` `{` ` ` `// If current character in X[] and Y are same,` ` ` `// then current character is part of LCS` ` ` `if` `(` `$X` `[` `$i` `- 1] == ` `$Y` `[` `$j` `- 1])` ` ` `{` ` ` `// Put current character in result` ` ` `$lcs` `[` `$index` `- 1] = ` `$X` `[` `$i` `- 1];` ` ` `$i` `--;` ` ` `$j` `--;` ` ` `$index` `--; ` `// reduce values of i, j and index` ` ` `}` ` ` ` ` `// If not same, then find the larger of two` ` ` `// and go in the direction of larger value` ` ` `else` `if` `(` `$L` `[` `$i` `- 1][` `$j` `] > ` `$L` `[` `$i` `][` `$j` `- 1])` ` ` `$i` `--;` ` ` `else` ` ` `$j` `--;` ` ` `}` ` ` ` ` `// Print the lcs` ` ` `echo` `"LCS of "` `. ` `$X` `. ` `" and "` `. ` `$Y` `. ` `" is "` `;` ` ` `for` `(` `$k` `= 0; ` `$k` `< ` `$temp` `; ` `$k` `++)` ` ` `echo` `$lcs` `[` `$k` `];` `}` `// Driver Code` `$X` `= ` `"AGGTAB"` `;` `$Y` `= ` `"GXTXAYB"` `;` `$m` `= ` `strlen` `(` `$X` `);` `$n` `= ` `strlen` `(` `$Y` `);` `lcs(` `$X` `, ` `$Y` `, ` `$m` `, ` `$n` `);` `// This code is contributed by ita_c` `?>` |

## Javascript

`<script>` `function` `ReverseString(str) {` ` ` `return` `str.split(` `''` `).reverse().join(` `''` `)` `}` ` ` `function` `max(a, b)` `{` ` ` `if` `(a > b)` ` ` `return` `a;` ` ` `else` ` ` `return` `b;` `}` `function` `printLCS(str1, str2) {` ` ` `var` `len1 = str1.length;` ` ` `var` `len2 = str2.length;` ` ` `var` `lcs = ` `new` `Array(len1 + 1);` ` ` `for` `(` `var` `i = 0; i <= len1; i++) {` ` ` `lcs[i] = ` `new` `Array(len2 + 1)` ` ` `}` ` ` `for` `(` `var` `i = 0; i <= len1; i++) {` ` ` `for` `(` `var` `j = 0; j <= len2; j++) {` ` ` `if` `(i == 0 || j == 0) {` ` ` `lcs[i][j] = 0;` ` ` `}` ` ` `else` `{` ` ` `if` `(str1[i - 1] == str2[j - 1]) {` ` ` `lcs[i][j] = 1 + lcs[i - 1][j - 1];` ` ` `}` ` ` `else` `{` ` ` `lcs[i][j] = max(lcs[i][j - 1], lcs[i - 1][j]);` ` ` `}` ` ` `}` ` ` `}}` ` ` ` ` `var` `n = lcs[len1][len2];` ` ` `document.write(` `"Length of common subsequence is: "` `+` ` ` `n + ` `"<br>"` `+ ` `"The subsequence is : "` `);` ` ` `var` `str=` `""` `;` ` ` `var` `i = len1;` ` ` `var` `j = len2;` ` ` `while` `(i>0&&j>0)` ` ` `{` ` ` `if` `(str1[i - 1] == str2[j - 1])` ` ` `{` ` ` `str += str1[i - 1];` ` ` `i--;` ` ` `j--;` ` ` `}` ` ` `else` `{` ` ` `if` `(lcs[i][j-1]>lcs[i-1][j])` ` ` `{` ` ` `j--;` ` ` `}` ` ` `else` ` ` `{` ` ` `i--;` ` ` `}` ` ` `}` ` ` `}` ` ` `return` `ReverseString(str);` ` ` `}` ` ` `var` `str1 = ` `"AGGTAB"` `;` ` ` `var` `str2 = ` `"GXTXAYB"` `;` ` ` `document.write(printLCS(str1, str2));` ` ` ` ` `// This code is contributed by akshitsaxenaa09` `</script>` |

**Output**

LCS of AGGTAB and GXTXAYB is GTAB

**Time Complexity:** O(m*n)**Auxiliary Space:** O(m*n)