 GeeksforGeeks App
Open App Browser
Continue

# Longest Common Substring | DP-29

Given two strings ‘X’ and ‘Y’, find the length of the longest common substring.

Examples :

Input : X = “GeeksforGeeks”, y = “GeeksQuiz”
Output : 5
Explanation:
The longest common substring is “Geeks” and is of length 5.

Input : X = “abcdxyz”, y = “xyzabcd”
Output :
Explanation:
The longest common substring is “abcd” and is of length 4.

Input : X = “zxabcdezy”, y = “yzabcdezx”
Output :
Explanation:
The longest common substring is “abcdez” and is of length 6. Approach:
Let m and n be the lengths of the first and second strings respectively.

A simple solution is to one by one consider all substrings of the first string and for every substring check if it is a substring in the second string. Keep track of the maximum length substring. There will be O(m^2) substrings and we can find whether a string is substring on another string in O(n) time (See this). So overall time complexity of this method would be O(n * m2)

Dynamic Programming can be used to find the longest common substring in O(m*n) time. The idea is to find the length of the longest common suffix for all substrings of both strings and store these lengths in a table.

The longest common suffix has following optimal substructure property.

If last characters match, then we reduce both lengths by 1

• LCSuff(X, Y, m, n) = LCSuff(X, Y, m-1, n-1) + 1 if X[m-1] = Y[n-1]

If last characters do not match, then result is 0, i.e.,

• LCSuff(X, Y, m, n) = 0 if (X[m-1] != Y[n-1])

Now we consider suffixes of different substrings ending at different indexes.
The maximum length Longest Common Suffix is the longest common substring.
LCSubStr(X, Y, m, n) = Max(LCSuff(X, Y, i, j)) where 1 <= i <= m and 1 <= j <= n

Following is the iterative implementation of the above solution.

## C++

 `/* Dynamic Programming solution to``   ``find length of the``   ``longest common substring */``#include ``#include ``using` `namespace` `std;` `/* Returns length of longest``   ``common substring of X[0..m-1]``   ``and Y[0..n-1] */``int` `LCSubStr(``char``* X, ``char``* Y, ``int` `m, ``int` `n)``{``    ``// Create a table to store``    ``// lengths of longest``    ``// common suffixes of substrings.  ``    ``// Note that LCSuff[i][j] contains``    ``// length of longest common suffix``    ``// of X[0..i-1] and Y[0..j-1].` `    ``int` `LCSuff[m + 1][n + 1];``    ``int` `result = 0; ``// To store length of the``                    ``// longest common substring` `    ``/* Following steps build LCSuff[m+1][n+1] in``        ``bottom up fashion. */``    ``for` `(``int` `i = 0; i <= m; i++)``    ``{``        ``for` `(``int` `j = 0; j <= n; j++)``        ``{``            ``// The first row and first column``            ``// entries have no logical meaning,``            ``// they are used only for simplicity``            ``// of program``            ``if` `(i == 0 || j == 0)``                ``LCSuff[i][j] = 0;` `            ``else` `if` `(X[i - 1] == Y[j - 1]) {``                ``LCSuff[i][j] = LCSuff[i - 1][j - 1] + 1;``                ``result = max(result, LCSuff[i][j]);``            ``}``            ``else``                ``LCSuff[i][j] = 0;``        ``}``    ``}``    ``return` `result;``}` `// Driver code``int` `main()``{``    ``char` `X[] = ``"OldSite:GeeksforGeeks.org"``;``    ``char` `Y[] = ``"NewSite:GeeksQuiz.com"``;` `    ``int` `m = ``strlen``(X);``    ``int` `n = ``strlen``(Y);` `    ``cout << ``"Length of Longest Common Substring is "``         ``<< LCSubStr(X, Y, m, n);``    ``return` `0;``}`

## Java

 `//  Java implementation of``// finding length of longest``// Common substring using``// Dynamic Programming``import` `java.io.*;` `class` `GFG {``    ``/*``       ``Returns length of longest common substring``       ``of X[0..m-1] and Y[0..n-1]``    ``*/``    ``static` `int` `LCSubStr(``char` `X[], ``char` `Y[], ``int` `m, ``int` `n)``    ``{``        ``// Create a table to store``        ``// lengths of longest common``        ``// suffixes of substrings.``        ``// Note that LCSuff[i][j]``        ``// contains length of longest``        ``// common suffix of``        ``// X[0..i-1] and Y[0..j-1].``        ``// The first row and first``        ``// column entries have no``        ``// logical meaning, they are``        ``// used only for simplicity of program``        ``int` `LCStuff[][] = ``new` `int``[m + ``1``][n + ``1``];` `        ``// To store length of the longest``        ``// common substring``        ``int` `result = ``0``;` `        ``// Following steps build``        ``// LCSuff[m+1][n+1] in bottom up fashion``        ``for` `(``int` `i = ``0``; i <= m; i++) {``            ``for` `(``int` `j = ``0``; j <= n; j++) {``                ``if` `(i == ``0` `|| j == ``0``)``                    ``LCStuff[i][j] = ``0``;``                ``else` `if` `(X[i - ``1``] == Y[j - ``1``]) {``                    ``LCStuff[i][j]``                        ``= LCStuff[i - ``1``][j - ``1``] + ``1``;``                    ``result = Integer.max(result,``                                         ``LCStuff[i][j]);``                ``}``                ``else``                    ``LCStuff[i][j] = ``0``;``            ``}``        ``}``        ``return` `result;``    ``}` `    ``// Driver Code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``String X = ``"OldSite:GeeksforGeeks.org"``;``        ``String Y = ``"NewSite:GeeksQuiz.com"``;` `        ``int` `m = X.length();``        ``int` `n = Y.length();` `        ``System.out.println(``            ``"Length of Longest Common Substring is "``            ``+ LCSubStr(X.toCharArray(), Y.toCharArray(), m,``                       ``n));``    ``}``}` `// This code is contributed by Sumit Ghosh`

## Python3

 `# Python3 implementation of Finding``# Length of Longest Common Substring` `# Returns length of longest common``# substring of X[0..m-1] and Y[0..n-1]`  `def` `LCSubStr(X, Y, m, n):` `    ``# Create a table to store lengths of``    ``# longest common suffixes of substrings.``    ``# Note that LCSuff[i][j] contains the``    ``# length of longest common suffix of``    ``# X[0...i-1] and Y[0...j-1]. The first``    ``# row and first column entries have no``    ``# logical meaning, they are used only``    ``# for simplicity of the program.` `    ``# LCSuff is the table with zero``    ``# value initially in each cell``    ``LCSuff ``=` `[[``0` `for` `k ``in` `range``(n``+``1``)] ``for` `l ``in` `range``(m``+``1``)]` `    ``# To store the length of``    ``# longest common substring``    ``result ``=` `0` `    ``# Following steps to build``    ``# LCSuff[m+1][n+1] in bottom up fashion``    ``for` `i ``in` `range``(m ``+` `1``):``        ``for` `j ``in` `range``(n ``+` `1``):``            ``if` `(i ``=``=` `0` `or` `j ``=``=` `0``):``                ``LCSuff[i][j] ``=` `0``            ``elif` `(X[i``-``1``] ``=``=` `Y[j``-``1``]):``                ``LCSuff[i][j] ``=` `LCSuff[i``-``1``][j``-``1``] ``+` `1``                ``result ``=` `max``(result, LCSuff[i][j])``            ``else``:``                ``LCSuff[i][j] ``=` `0``    ``return` `result`  `# Driver Code``X ``=` `'OldSite:GeeksforGeeks.org'``Y ``=` `'NewSite:GeeksQuiz.com'` `m ``=` `len``(X)``n ``=` `len``(Y)` `print``(``'Length of Longest Common Substring is'``,``      ``LCSubStr(X, Y, m, n))` `# This code is contributed by Soumen Ghosh`

## C#

 `// C# implementation of finding length of longest``// Common substring using Dynamic Programming``using` `System;` `class` `GFG {` `    ``// Returns length of longest common``    ``// substring of X[0..m-1] and Y[0..n-1]``    ``static` `int` `LCSubStr(``string` `X, ``string` `Y, ``int` `m, ``int` `n)``    ``{` `        ``// Create a table to store lengths of``        ``// longest common suffixes of substrings.``        ``// Note that LCSuff[i][j] contains length``        ``// of longest common suffix of X[0..i-1]``        ``// and Y[0..j-1]. The first row and first``        ``// column entries have no logical meaning,``        ``// they are used only for simplicity of``        ``// program``        ``int``[, ] LCStuff = ``new` `int``[m + 1, n + 1];` `        ``// To store length of the longest common``        ``// substring``        ``int` `result = 0;` `        ``// Following steps build LCSuff[m+1][n+1]``        ``// in bottom up fashion``        ``for` `(``int` `i = 0; i <= m; i++)``        ``{``            ``for` `(``int` `j = 0; j <= n; j++)``            ``{``                ``if` `(i == 0 || j == 0)``                    ``LCStuff[i, j] = 0;``                ``else` `if` `(X[i - 1] == Y[j - 1])``                ``{``                    ``LCStuff[i, j]``                        ``= LCStuff[i - 1, j - 1] + 1;` `                    ``result``                        ``= Math.Max(result, LCStuff[i, j]);``                ``}``                ``else``                    ``LCStuff[i, j] = 0;``            ``}``        ``}` `        ``return` `result;``    ``}` `    ``// Driver Code``    ``public` `static` `void` `Main()``    ``{``        ``String X = ``"OldSite:GeeksforGeeks.org"``;``        ``String Y = ``"NewSite:GeeksQuiz.com"``;` `        ``int` `m = X.Length;``        ``int` `n = Y.Length;` `        ``Console.Write(``"Length of Longest Common"``                      ``+ ``" Substring is "``                      ``+ LCSubStr(X, Y, m, n));``    ``}``}` `// This code is contributed by Sam007.`

## PHP

 ``

## Javascript

 ``

Output

`Length of Longest Common Substring is 10`

Time Complexity: O(m*n)
Auxiliary Space: O(m*n), since m*n extra space has been taken.

Another Approach: (Space optimized approach).
In the above approach, we are only using the last row of the 2-D array only, hence we can optimize the space by using
a 2-D array of dimension 2*(min(n,m)).

Below is the implementation of the above approach:

## C++

 `// C++ implementation of the above approach``#include ``using` `namespace` `std;` `// Function to find the length of the``// longest LCS``int` `LCSubStr(string s, string t, ``int` `n, ``int` `m)``{``  ` `    ``// Create DP table``    ``int` `dp[m + 1];``    ``int` `res = 0;` `    ``for` `(``int` `i = 1; i <= n; i++) {``        ``for` `(``int` `j = 1; j <= m; j++) {``            ``if` `(s[i - 1] == t[j - 1]) {``                ``dp[i % 2][j] = dp[(i - 1) % 2][j - 1] + 1;``                ``if` `(dp[i % 2][j] > res)``                    ``res = dp[i % 2][j];``            ``}``            ``else``                ``dp[i % 2][j] = 0;``        ``}``    ``}``    ``return` `res;``}` `// Driver Code``int` `main()``{``    ``string X = ``"OldSite:GeeksforGeeks.org"``;``    ``string Y = ``"NewSite:GeeksQuiz.com"``;` `    ``int` `m = X.length();``    ``int` `n = Y.length();` `    ``cout << LCSubStr(X, Y, m, n);``    ``return` `0;``    ``cout << ``"GFG!"``;``    ``return` `0;``}` `// This code is contributed by rajsanghavi9.`

## Java

 `// Java implementation of the above approach``import` `java.io.*;``class` `GFG``{``  ` `    ``// Function to find the length of the``    ``// longest LCS``    ``static` `int` `LCSubStr(String s,String t,``                        ``int` `n,``int` `m)``    ``{ ``      ` `        ``// Create DP table``        ``int` `dp[][]=``new` `int``[``2``][m+``1``];``        ``int` `res=``0``;``     ` `        ``for``(``int` `i=``1``;i<=n;i++)``        ``{``            ``for``(``int` `j=``1``;j<=m;j++)``            ``{``                ``if``(s.charAt(i-``1``)==t.charAt(j-``1``))``                ``{``                    ``dp[i%``2``][j]=dp[(i-``1``)%``2``][j-``1``]+``1``;``                    ``if``(dp[i%``2``][j]>res)``                        ``res=dp[i%``2``][j];``                ``}``                ``else` `dp[i%``2``][j]=``0``;``            ``}``        ``}``        ``return` `res;``    ``}``  ` `    ``// Driver Code``    ``public` `static` `void` `main (String[] args)``    ``{``        ``String X=``"OldSite:GeeksforGeeks.org"``;``        ``String Y=``"NewSite:GeeksQuiz.com"``;``        ` `        ``int` `m=X.length();``        ``int` `n=Y.length();``        ` `        ``// Function call``        ``System.out.println(LCSubStr(X,Y,m,n));``        ` `    ``}``}`

## Python3

 `# Python implementation of the above approach` `# Function to find the length of the``# longest LCS``def` `LCSubStr(s, t, n, m):``  ` `    ``# Create DP table``    ``dp ``=` `[[``0` `for` `i ``in` `range``(m ``+` `1``)] ``for` `j ``in` `range``(``2``)]``    ``res ``=` `0``    ` `    ``for` `i ``in` `range``(``1``,n ``+` `1``):``        ``for` `j ``in` `range``(``1``,m ``+` `1``):``            ``if``(s[i ``-` `1``] ``=``=` `t[j ``-` `1``]):``                ``dp[i ``%` `2``][j] ``=` `dp[(i ``-` `1``) ``%` `2``][j ``-` `1``] ``+` `1``                ``if``(dp[i ``%` `2``][j] > res):``                    ``res ``=` `dp[i ``%` `2``][j]``            ``else``:``                ``dp[i ``%` `2``][j] ``=` `0``    ``return` `res` `# Driver Code``X ``=` `"OldSite:GeeksforGeeks.org"``Y ``=` `"NewSite:GeeksQuiz.com"``m ``=` `len``(X)``n ``=` `len``(Y)` `# Function call``print``(LCSubStr(X,Y,m,n))` `# This code is contributed by avanitrachhadiya2155`

## C#

 `// C# implementation of the above approach``using` `System;``public` `class` `GFG``{` `  ``// Function to find the length of the``  ``// longest LCS``  ``static` `int` `LCSubStr(``string` `s,``string` `t,``                      ``int` `n,``int` `m)``  ``{ ` `    ``// Create DP table``    ``int``[,] dp = ``new` `int``[2, m + 1];``    ``int` `res = 0;` `    ``for``(``int` `i = 1; i <= n; i++)``    ``{``      ``for``(``int` `j = 1; j <= m; j++)``      ``{``        ``if``(s[i - 1] == t[j - 1])``        ``{``          ``dp[i % 2, j] = dp[(i - 1) % 2, j - 1] + 1;``          ``if``(dp[i % 2, j] > res)``            ``res = dp[i % 2, j];``        ``}``        ``else` `dp[i % 2, j] = 0;``      ``}``    ``}``    ``return` `res;``  ``}` `  ``// Driver Code``  ``static` `public` `void` `Main (){``    ``string` `X = ``"OldSite:GeeksforGeeks.org"``;``    ``string` `Y = ``"NewSite:GeeksQuiz.com"``;` `    ``int` `m = X.Length;``    ``int` `n = Y.Length;` `    ``// Function call``    ``Console.WriteLine(LCSubStr(X,Y,m,n));``  ``}``}` `// This code is contributed by rag2127`

## Javascript

 ``

Output

`10`

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

Another Approach: (Using recursion)
Here is the recursive solution of the above approach.

## C++

 `// C++ program using to find length of the``// longest common substring  recursion``#include ` `using` `namespace` `std;` `string X, Y;` `// Returns length of function f``// or longest common substring``// of X[0..m-1] and Y[0..n-1]``int` `lcs(``int` `i, ``int` `j, ``int` `count)``{` `    ``if` `(i == 0 || j == 0)``        ``return` `count;` `    ``if` `(X[i - 1] == Y[j - 1]) {``        ``count = lcs(i - 1, j - 1, count + 1);``    ``}``    ``count = max(count,``                ``max(lcs(i, j - 1, 0),``                    ``lcs(i - 1, j, 0)));``    ``return` `count;``}` `// Driver code``int` `main()``{``    ``int` `n, m;` `    ``X = ``"abcdxyz"``;``    ``Y = ``"xyzabcd"``;` `    ``n = X.size();``    ``m = Y.size();` `    ``cout << lcs(n, m, 0);` `    ``return` `0;``}`

## Java

 `// Java program using to find length of the``// longest common substring recursion``import` `java.io.*;``class` `GFG {` `    ``static` `String X, Y;``    ``// Returns length of function``    ``// for longest common``    ``// substring of X[0..m-1] and Y[0..n-1]``    ``static` `int` `lcs(``int` `i, ``int` `j, ``int` `count)``    ``{` `        ``if` `(i == ``0` `|| j == ``0``)``        ``{``            ``return` `count;``        ``}` `        ``if` `(X.charAt(i - ``1``)``            ``== Y.charAt(j - ``1``))``        ``{``            ``count = lcs(i - ``1``, j - ``1``, count + ``1``);``        ``}``        ``count = Math.max(count,``                         ``Math.max(lcs(i, j - ``1``, ``0``),``                                  ``lcs(i - ``1``, j, ``0``)));``        ``return` `count;``    ``}``    ` `    ``// Driver code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``int` `n, m;``        ``X = ``"abcdxyz"``;``        ``Y = ``"xyzabcd"``;` `        ``n = X.length();``        ``m = Y.length();` `        ``System.out.println(lcs(n, m, ``0``));``    ``}``}``// This code is contributed by Rajput-JI`

## Python3

 `# Python3 program using to find length of``# the longest common substring recursion` `# Returns length of function for longest``# common substring of X[0..m-1] and Y[0..n-1]`  `def` `lcs(i, j, count):` `    ``if` `(i ``=``=` `0` `or` `j ``=``=` `0``):``        ``return` `count` `    ``if` `(X[i ``-` `1``] ``=``=` `Y[j ``-` `1``]):``        ``count ``=` `lcs(i ``-` `1``, j ``-` `1``, count ``+` `1``)` `    ``count ``=` `max``(count, ``max``(lcs(i, j ``-` `1``, ``0``),``                           ``lcs(i ``-` `1``, j, ``0``)))` `    ``return` `count`  `# Driver code``if` `__name__ ``=``=` `"__main__"``:` `    ``X ``=` `"abcdxyz"``    ``Y ``=` `"xyzabcd"` `    ``n ``=` `len``(X)``    ``m ``=` `len``(Y)` `    ``print``(lcs(n, m, ``0``))` `# This code is contributed by Ryuga`

## C#

 `// C# program using to find length``// of the longest common substring``// recursion``using` `System;` `class` `GFG {``    ``static` `String X, Y;` `    ``// Returns length of function for``    ``// longest common substring of``    ``// X[0..m-1] and Y[0..n-1]``    ``static` `int` `lcs(``int` `i, ``int` `j, ``int` `count)``    ``{` `        ``if` `(i == 0 || j == 0) {``            ``return` `count;``        ``}` `        ``if` `(X[i - 1] == Y[j - 1]) {``            ``count = lcs(i - 1, j - 1, count + 1);``        ``}``        ``count = Math.Max(count, Math.Max(lcs(i, j - 1, 0),``                                         ``lcs(i - 1, j, 0)));``        ``return` `count;``    ``}` `    ``// Driver code``    ``public` `static` `void` `Main()``    ``{``        ``int` `n, m;``        ``X = ``"abcdxyz"``;``        ``Y = ``"xyzabcd"``;` `        ``n = X.Length;``        ``m = Y.Length;` `        ``Console.Write(lcs(n, m, 0));``    ``}``}` `// This code is contributed by Rajput-JI`

## PHP

 ``

## Javascript

 ``

Output

`4`

Time complexity: O(2^max(m,n)) as the function is doing two recursive calls – lcs(i, j-1, 0) and lcs(i-1, j, 0) when characters at X[i-1] != Y[j-1]. So it will give a worst case time complexity as 2^N, where N = max(m, n), m and n is the length of X and Y string.
Auxiliary Space: O(1): as the function call is not using any extra space (function is just using a recursive call stack which we generally doesn’t consider in auxiliary space).