Given two strings, find the length of 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 a typical dynamic programming-based solution for LCS. We can optimize the space used by LCS problem. We know the recurrence relationship of the LCS problem is
CPP
int lcs(string &X, string &Y)
{
int m = X.length(), n = Y.length();
int L[m+1][n+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]);
}
}
return L[m][n];
}
|
Java
import java.io.*;
class GFG {
public static int lcs(String X, String Y)
{
int m = X.length(), n = Y.length();
int L[][] = new int [m + 1 ][n + 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 ]);
}
}
return L[m][n];
}
}
|
C#
using System;
class GFG{
public static int lcs( string X, string Y)
{
int m = X.Length, n = Y.Length;
int [,] L = new int [m + 1, n + 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]);
}
}
return L[m, n];
}
}
|
Javascript
<script>
function max(a, b)
{
if (a > b)
return a;
else
return b;
}
function lcs(X, Y, m, n)
{
var L = new Array(m + 1);
for ( var i = 0; i < L.length; i++)
{
L[i] = new Array(n + 1);
}
var i, j;
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]);
}
}
return L[m][n];
}
</script>
|
Python3
def lcs(X, Y):
m = len (X)
n = len (Y)
L = [[ 0 for j in range (n + 1 )] for i in range (m + 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 ])
return L[m][n]
|
How to find the length of LCS is O(n) auxiliary space?
We strongly recommend that you click here and practice it, before moving on to the solution.
One important observation in the above simple implementation is, in each iteration of the outer loop we only need values from all columns of the previous row. So there is no need to store all rows in our DP matrix, we can just store two rows at a time and use them. In that way, used space will be reduced from L[m+1][n+1] to L[2][n+1]. Below is the implementation of the above idea.
C++
#include<bits/stdc++.h>
using namespace std;
int lcs(string &X, string &Y)
{
int m = X.length(), n = Y.length();
int L[2][n + 1];
bool bi;
for ( int i = 0; i <= m; i++)
{
bi = i & 1;
for ( int j = 0; j <= n; j++)
{
if (i == 0 || j == 0)
L[bi][j] = 0;
else if (X[i-1] == Y[j-1])
L[bi][j] = L[1 - bi][j - 1] + 1;
else
L[bi][j] = max(L[1 - bi][j],
L[bi][j - 1]);
}
}
return L[bi][n];
}
int main()
{
string X = "AGGTAB" ;
string Y = "GXTXAYB" ;
printf ( "Length of LCS is %d\n" , lcs(X, Y));
return 0;
}
|
Java
import java.io.*;
class GFG {
public static int lcs(String X, String Y)
{
int m = X.length(), n = Y.length();
int L[][] = new int [ 2 ][n + 1 ];
int bi = 0 ;
for ( int i = 0 ; i <= m; i++) {
bi = i & 1 ;
for ( int j = 0 ; j <= n; j++) {
if (i == 0 || j == 0 )
L[bi][j] = 0 ;
else if (X.charAt(i - 1 ) == Y.charAt(j - 1 ))
L[bi][j] = L[ 1 - bi][j - 1 ] + 1 ;
else
L[bi][j] = Math.max(L[ 1 - bi][j],
L[bi][j - 1 ]);
}
}
return L[bi][n];
}
public static void main(String[] args)
{
String X = "AGGTAB" ;
String Y = "GXTXAYB" ;
System.out.println( "Length of LCS is " + lcs(X, Y));
}
}
|
Python3
def lcs(X, Y):
m = len (X)
n = len (Y)
L = [[ 0 for i in range (n + 1 )] for j in range ( 2 )]
bi = bool
for i in range (m):
bi = i& 1
for j in range (n + 1 ):
if (i = = 0 or j = = 0 ):
L[bi][j] = 0
elif (X[i] = = Y[j - 1 ]):
L[bi][j] = L[ 1 - bi][j - 1 ] + 1
else :
L[bi][j] = max (L[ 1 - bi][j],
L[bi][j - 1 ])
return L[bi][n]
X = "AGGTAB"
Y = "GXTXAYB"
print ( "Length of LCS is" , lcs(X, Y))
|
C#
using System;
class GFG
{
public static int lcs( string X,
string Y)
{
int m = X.Length, n = Y.Length;
int [,]L = new int [2, n + 1];
int bi = 0;
for ( int i = 0; i <= m; i++)
{
bi = i & 1;
for ( int j = 0; j <= n; j++)
{
if (i == 0 || j == 0)
L[bi, j] = 0;
else if (X[i - 1] == Y[j - 1])
L[bi, j] = L[1 - bi,
j - 1] + 1;
else
L[bi, j] = Math.Max(L[1 - bi, j],
L[bi, j - 1]);
}
}
return L[bi, n];
}
public static void Main()
{
string X = "AGGTAB" ;
string Y = "GXTXAYB" ;
Console.Write( "Length of LCS is " +
lcs(X, Y));
}
}
|
PHP
<?php
function lcs( $X , $Y )
{
$m = strlen ( $X );
$n = strlen ( $Y );
$L = array ( array ());
for ( $i = 0; $i <= $m ; $i ++)
{
$bi = $i & 1;
for ( $j = 0; $j <= $n ; $j ++)
{
if ( $i == 0 || $j == 0)
$L [ $bi ][ $j ] = 0;
else if ( $X [ $i - 1] == $Y [ $j - 1])
$L [ $bi ][ $j ] = $L [1 - $bi ][ $j - 1] + 1;
else
$L [ $bi ][ $j ] = max( $L [1 - $bi ][ $j ],
$L [ $bi ][ $j - 1]);
}
}
return $L [ $bi ][ $n ];
}
$X = "AGGTAB" ;
$Y = "GXTXAYB" ;
echo "Length of LCS is : " ,
lcs( $X , $Y );
?>
|
Javascript
<script>
function lcs(X, Y)
{
let m = X.length, n = Y.length;
let L = new Array(2);
for (let i = 0; i < 2; i++)
{
L[i] = new Array(n + 1);
for (let j = 0; j < n + 1; j++)
{
L[i][j] = 0;
}
}
let bi=0;
for (let i = 0; i <= m; i++)
{
bi = i & 1;
for (let j = 0; j <= n; j++)
{
if (i == 0 || j == 0)
L[bi][j] = 0;
else if (X[i - 1] ==
Y[j - 1])
L[bi][j] = L[1 - bi][j - 1] + 1;
else
L[bi][j] = Math.max(L[1 - bi][j],
L[bi][j - 1]);
}
}
return L[bi][n];
}
let X = "AGGTAB" ;
let Y = "GXTXAYB" ;
document.write( "Length of LCS is " +
lcs(X, Y));
</script>
|
Output
Length of LCS is 4
Time Complexity : O(m*n)
Auxiliary Space: O(n)
We can further improve the space complexity of above program
C++
#include <iostream>
using namespace std;
int lcs( const string& s1, const string& s2)
{
int m = s1.length(), n = s2.length();
int db[n + 1] = {};
for ( int i = 1; i <= m; ++i) {
int prev = db[0];
for ( int j = 1; j <= n; ++j) {
int temp = db[j];
if (s1[i - 1] == s2[j - 1])
db[j] = 1 + prev;
else
db[j] = max(db[j - 1], db[j]);
prev = temp;
}
}
return db[n];
}
int main()
{
string s1 = "AGGTAB" , s2 = "GXTXAYB" ;
int r = lcs(s1, s2);
cout << "Length of LCS is " << lcs(s1, s2);
return 0;
}
|
Java
import java.io.*;
class GFG {
public static int lcs(String text1, String text2) {
int [] dp = new int [text2.length()+ 1 ];
for ( int i = 0 ; i< text1.length(); i++){
int prev = dp[ 0 ];
for ( int j = 1 ; j < dp.length; j++){
int temp = dp[j];
if (text1.charAt(i) != text2.charAt(j- 1 )){
dp[j] = Math.max(dp[j- 1 ], dp[j]);
} else {
dp[j] = prev + 1 ;
}
prev = temp;
}
}
return dp[dp.length- 1 ];
}
public static void main(String[] args)
{
String X = "AGGTAB" ;
String Y = "GXTXAYB" ;
System.out.println( "Length of LCS is " + lcs(X, Y));
}
}
|
Python3
def lcs(text1, text2):
m, n = len (text1), len (text2)
if m > n : text1, text2 = text2, text1
dp = [ 0 ] * (n + 1 )
for c in text1:
prev = 0
for i, d in enumerate (text2):
prev, dp[i + 1 ] = dp[i + 1 ], prev + 1 if c = = d else max (dp[i], dp[i + 1 ])
return dp[ - 1 ]
X = "AGGTAB"
Y = "GXTXAYB"
print ( "Length of LCS is" , lcs(X, Y))
|
C#
using System;
class GFG
{
public static int lcs( string text1, string text2)
{
int [] dp = new int [text2.Length + 1];
for ( int i = 0; i < text1.Length; i++)
{
int prev = dp[0];
for ( int j = 1; j < dp.Length; j++)
{
int temp = dp[j];
if (text1[i] != text2[j - 1])
{
dp[j] = Math.Max(dp[j - 1], dp[j]);
}
else
{
dp[j] = prev + 1;
}
prev = temp;
}
}
return dp[dp.Length - 1];
}
public static void Main( string [] args)
{
string X = "AGGTAB" ;
string Y = "GXTXAYB" ;
Console.WriteLine( "Length of LCS is " + lcs(X, Y));
}
}
|
Javascript
function lcs(s1, s2)
{
let m = s1.length, n = s2.length;
let db = Array(n + 1).fill(0);
for (let i = 1; i <= m; ++i)
{
let prev = db[0];
for (let j = 1; j <= n; ++j)
{
let temp = db[j];
if (s1[i - 1] === s2[j - 1])
db[j] = 1 + prev;
else
db[j] = Math.max(db[j - 1], db[j]);
prev = temp;
}
}
return db[n];
}
let s1 = "AGGTAB" , s2 = "GXTXAYB" ;
let r = lcs(s1, s2);
console.log( "Length of LCS is " + r);
|
Output
Length of LCS is 4
Time Complexity : O(m*n)
Auxiliary Space: O(n) as Earlier is 2N space is used but complexity Remains same as Space complexity is doesn’t depend the no. to which n is multiply
This article is contributed Shivam Mittal. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
04 Apr, 2023
Like Article
Save Article