# Dynamic Programming | Set 29 (Longest Common Substring)

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

Examples :

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

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

Input : X = "zxabcdezy", y = "yzabcdezx"
Output : 6
The longest common substring is "abcdez" and is of
length 6.
```

## Recommended: Please solve it on “PRACTICE ” first, before moving on to the solution.

Let m and n be the lengths of first and second strings respectively.

A simple solution is to one by one consider all substrings of first string and for every substring check if it is a substring in second string. Keep track of the maximum length substring. There will be O(m^2) substrings and we can find whether a string is subsring 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 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
LCSuff(X, Y, m, n) = LCSuff(X, Y, m-1, n-1) + 1 if X[m-1] = Y[n-1]
0  Otherwise (if X[m-1] != Y[n-1])

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 C++ implementation of the above solution.

## C++

```/* Dynamic Programming solution to find length of the
longest common substring */
#include<iostream>
#include<string.h>
using namespace std;

// A utility function to find maximum of two integers
int max(int a, int b)
{   return (a > b)? a : b; }

/* 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.   Notethat 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 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++)
{
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 program to test above function */
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
public class LongestCommonSubSequence
{
/*
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];
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++)
{
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 Program to test above function
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
```

Output:
`Length of Longest Common Substring is 10`

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

The longest substring can also be solved in O(n+m) time using Suffix Tree. We will be covering Suffix Tree based solution in a separate post.

Exercise: The above solution prints only length of the longest common substring. Extend the solution to print the substring also.

# GATE CS Corner    Company Wise Coding Practice

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.
2.8 Average Difficulty : 2.8/5.0
Based on 81 vote(s)
{"found_math": false, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 0, "mathjax_display_tex": 0, "mathjax_asciimath": 0, "img_math": 0, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0, "katex": 0, "math-container": 0, "wp-katex-eq": 0, "align": 0, "equation": 0, "x-ck12": 0, "texerror": 0}