# Print the longest common substring

Given two strings ‘X’ and ‘Y’, print the length of the longest common substring. If two or more substrings have the same value for longest common substring, then print any one of them.

Examples:

```Input :  X = "GeeksforGeeks",
Y = "GeeksQuiz"
Output : Geeks

Input : X = "zxabcdezy",
Y = "yzabcdezx"
Output : abcdez
```

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

We have discussed a solution to find length of longest common string. In this post, we have discussed printing common string is discussed.

Naive Approach: Let strings X and Y be the lengths m and n respectively. Generate all possible substrings of X which requires a time complexity of O(m2) and search each substring in the string Y which can be achieved in O(n) time complexity using KMP algorithm. Overall time complexity will be O(n * m2).

Efficient Approach: It is based on the dynamic programming implementation explained in this post. The longest suffix matrix LCSuff[][] is build up and the index of the cell having the maximum value is tracked. Let that index be represented by (row, col) pair. Now the final longest common substring is build with the help of that index by diagonally traversing up the LCSuff[][] matrix until LCSuff[row][col] != 0 and during the iteration obtaining the characters either from X[row-1] or Y[col-1] and adding them from right to left in the resultant common string.

## C++

 `// C++ implementation to print the longest common substring ` `#include ` `#include ` `#include ` ` `  `using` `namespace` `std; ` ` `  `/* function to find and print the longest common  ` `   ``substring of X[0..m-1] and Y[0..n-1] */` `void` `printLCSubStr(``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` `LCSuff[m + 1][n + 1]; ` ` `  `    ``// To store length of the longest common substring ` `    ``int` `len = 0; ` ` `  `    ``// To store the index of the cell which contains the ` `    ``// maximum value. This cell's index helps in building ` `    ``// up the longest common substring from right to left. ` `    ``int` `row, col; ` ` `  `    ``/* 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; ` `                ``if` `(len < LCSuff[i][j]) { ` `                    ``len = LCSuff[i][j]; ` `                    ``row = i; ` `                    ``col = j; ` `                ``} ` `            ``} ` `            ``else` `                ``LCSuff[i][j] = 0; ` `        ``} ` `    ``} ` ` `  `    ``// if true, then no common substring exists ` `    ``if` `(len == 0) { ` `        ``cout << ``"No Common Substring"``; ` `        ``return``; ` `    ``} ` ` `  `    ``// allocate space for the longest common substring ` `    ``char``* resultStr = (``char``*)``malloc``((len + 1) * ``sizeof``(``char``)); ` ` `  `    ``// traverse up diagonally form the (row, col) cell ` `    ``// until LCSuff[row][col] != 0 ` `    ``while` `(LCSuff[row][col] != 0) { ` `        ``resultStr[--len] = X[row - 1]; ``// or Y[col-1] ` ` `  `        ``// move diagonally up to previous cell ` `        ``row--; ` `        ``col--; ` `    ``} ` ` `  `    ``// required longest common substring ` `    ``cout << resultStr; ` `} ` ` `  `/* 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); ` ` `  `    ``printLCSubStr(X, Y, m, n); ` `    ``return` `0; ` `} `

## Java

 `// Java implementation to print the longest common substring ` `public` `class` `Longest_common_substr { ` ` `  `    ``/* function to find and print the longest common  ` `       ``substring of X[0..m-1] and Y[0..n-1] */` `    ``static` `void` `printLCSubStr(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``[][] LCSuff = ``new` `int``[m + ``1``][n + ``1``]; ` ` `  `        ``// To store length of the longest common substring ` `        ``int` `len = ``0``; ` ` `  `        ``// To store the index of the cell which contains the ` `        ``// maximum value. This cell's index helps in building ` `        ``// up the longest common substring from right to left. ` `        ``int` `row = ``0``, col = ``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``) ` `                    ``LCSuff[i][j] = ``0``; ` ` `  `                ``else` `if` `(X.charAt(i - ``1``) == Y.charAt(j - ``1``)) { ` `                    ``LCSuff[i][j] = LCSuff[i - ``1``][j - ``1``] + ``1``; ` `                    ``if` `(len < LCSuff[i][j]) { ` `                        ``len = LCSuff[i][j]; ` `                        ``row = i; ` `                        ``col = j; ` `                    ``} ` `                ``} ` `                ``else` `                    ``LCSuff[i][j] = ``0``; ` `            ``} ` `        ``} ` ` `  `        ``// if true, then no common substring exists ` `        ``if` `(len == ``0``) { ` `            ``System.out.println(``"No Common Substring"``); ` `            ``return``; ` `        ``} ` ` `  `        ``// allocate space for the longest common substring ` `        ``String resultStr = ``""``; ` ` `  `        ``// traverse up diagonally form the (row, col) cell ` `        ``// until LCSuff[row][col] != 0 ` `        ``while` `(LCSuff[row][col] != ``0``) { ` `            ``resultStr = X.charAt(row - ``1``) + resultStr; ``// or Y[col-1] ` `            ``--len; ` ` `  `            ``// move diagonally up to previous cell ` `            ``row--; ` `            ``col--; ` `        ``} ` ` `  `        ``// required longest common substring ` `        ``System.out.println(resultStr); ` `    ``} ` ` `  `    ``/* 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(); ` ` `  `        ``printLCSubStr(X, Y, m, n); ` `    ``} ` `} ` `// This code is contributed by Sumit Ghosh `

## Python3

 `# Python3 implementation to print ` `# the longest common substring ` ` `  `# function to find and print   ` `# the longest common substring of ` `# X[0..m-1] and Y[0..n-1] ` `def` `printLCSSubStr(X: ``str``, Y: ``str``,  ` `                   ``m: ``int``, n: ``int``): ` ` `  `    ``# 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 ` `    ``LCSuff ``=` `[[``0` `for` `i ``in` `range``(n ``+` `1``)]  ` `                 ``for` `j ``in` `range``(m ``+` `1``)] ` ` `  `    ``# To store length of the  ` `    ``# longest common substring ` `    ``length ``=` `0` ` `  `    ``# To store the index of the cell  ` `    ``# which contains the maximum value.  ` `    ``# This cell's index helps in building ` `    ``# up the longest common substring  ` `    ``# from right to left. ` `    ``row, col ``=` `0``, ``0` ` `  `    ``# Following steps 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` `                ``if` `length < LCSuff[i][j]: ` `                    ``length ``=` `LCSuff[i][j] ` `                    ``row ``=` `i ` `                    ``col ``=` `j ` `            ``else``: ` `                ``LCSuff[i][j] ``=` `0` ` `  `    ``# if true, then no common substring exists ` `    ``if` `length ``=``=` `0``: ` `        ``print``(``"No Common Substring"``) ` `        ``return` ` `  `    ``# allocate space for the longest ` `    ``# common substring ` `    ``resultStr ``=` `[``'0'``] ``*` `length ` ` `  `    ``# traverse up diagonally form the  ` `    ``# (row, col) cell until LCSuff[row][col] != 0 ` `    ``while` `LCSuff[row][col] !``=` `0``: ` `        ``length ``-``=` `1` `        ``resultStr[length] ``=` `X[row ``-` `1``] ``# or Y[col-1] ` ` `  `        ``# move diagonally up to previous cell ` `        ``row ``-``=` `1` `        ``col ``-``=` `1` ` `  `    ``# required longest common substring ` `    ``print``(''.join(resultStr)) ` ` `  `# Driver Code ` `if` `__name__ ``=``=` `"__main__"``: ` `    ``X ``=` `"OldSite:GeeksforGeeks.org"` `    ``Y ``=` `"NewSite:GeeksQuiz.com"` `    ``m ``=` `len``(X) ` `    ``n ``=` `len``(Y) ` ` `  `    ``printLCSSubStr(X, Y, m, n) ` ` `  `# This code is contributed by ` `# sanjeev2552 `

## C#

 `// C# implementation to print the ` `// longest common substring ` `using` `System; ` ` `  `class` `GFG { ` ` `  `    ``/* function to find and print the longest common  ` `    ``substring of X[0..m-1] and Y[0..n-1] */` `    ``static` `void` `printLCSubStr(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``[, ] LCSuff = ``new` `int``[m + 1, n + 1]; ` ` `  `        ``// To store length of the longest common substring ` `        ``int` `len = 0; ` ` `  `        ``// To store the index of the cell which contains the ` `        ``// maximum value. This cell's index helps in building ` `        ``// up the longest common substring from right to left. ` `        ``int` `row = 0, col = 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) ` `                    ``LCSuff[i, j] = 0; ` ` `  `                ``else` `if` `(X[i - 1] == Y[j - 1]) { ` `                    ``LCSuff[i, j] = LCSuff[i - 1, j - 1] + 1; ` `                    ``if` `(len < LCSuff[i, j]) { ` `                        ``len = LCSuff[i, j]; ` `                        ``row = i; ` `                        ``col = j; ` `                    ``} ` `                ``} ` `                ``else` `                    ``LCSuff[i, j] = 0; ` `            ``} ` `        ``} ` ` `  `        ``// if true, then no common substring exists ` `        ``if` `(len == 0) { ` `            ``Console.Write(``"No Common Substring"``); ` `            ``return``; ` `        ``} ` ` `  `        ``// allocate space for the longest common substring ` `        ``String resultStr = ``""``; ` ` `  `        ``// traverse up diagonally form the (row, col) cell ` `        ``// until LCSuff[row][col] != 0 ` `        ``while` `(LCSuff[row, col] != 0) { ` `            ``resultStr = X[row - 1] + resultStr; ``// or Y[col-1] ` `            ``--len; ` ` `  `            ``// move diagonally up to previous cell ` `            ``row--; ` `            ``col--; ` `        ``} ` ` `  `        ``// required longest common substring ` `        ``Console.WriteLine(resultStr); ` `    ``} ` ` `  `    ``/* Driver program to test above function */` `    ``public` `static` `void` `Main() ` `    ``{ ` `        ``String X = ``"OldSite:GeeksforGeeks.org"``; ` `        ``String Y = ``"NewSite:GeeksQuiz.com"``; ` ` `  `        ``int` `m = X.Length; ` `        ``int` `n = Y.Length; ` ` `  `        ``printLCSubStr(X, Y, m, n); ` `    ``} ` `} ` ` `  `// This code is contributed by Sam007 `

Output:

```Site:Geeks
```

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

Space Optimized Approach:

The auxiliary space used by the solution above is O(m*n), where m and n are lengths of string X and Y. The space used by the above solution can be reduced to O(2*n). A variable end is used to store ending point of the longest common substring in string X and variable maxlen is used to store the length of the longest common substring.
Suppose we are at DP state when the length of X is i and length of Y is j, the result of which is stored in len[i][j].
Now if X[i-1] == Y[j-1], then len[i][j] = 1 + len[i-1][j-1], that is result of current row in matrix len[][] depends on values from previous row. Hence the required length of longest common substring can be obtained by maintaining values of two consecutive rows only, thereby reducing space requirements to O(2*n).
To print the longest common substring, we use variable end. When len[i][j] is calculated, it is compared with maxlen. If maxlen is less than len[i][j], then end is updated to i-1 to show that longest common substring ends at index i-1 in X and maxlen is updated to len[i][j]. The longest common substring then is from index end – maxlen + 1 to index end in X.
A variable currRow is used to represent that either row 0 or row 1 of len[n] matrix is currently used to find the length. Initially, row 0 is used as the current row for the case when the length of string X is zero. At the end of each iteration, the current row is made the previous row and the previous row is made the new current row.

Given below is the implementation of the above approach:

## C++

 `// Space optimized CPP implementation to print ` `// longest common substring. ` `#include ` `using` `namespace` `std; ` ` `  `// Function to find longest common substring. ` `string LCSubStr(string X, string Y) ` `{ ` `    ``// Find length of both the strings. ` `    ``int` `m = X.length(); ` `    ``int` `n = Y.length(); ` ` `  `    ``// Variable to store length of longest ` `    ``// common substring. ` `    ``int` `result = 0; ` ` `  `    ``// Variable to store ending point of ` `    ``// longest common substring in X. ` `    ``int` `end; ` ` `  `    ``// Matrix to store result of two ` `    ``// consecutive rows at a time. ` `    ``int` `len[n]; ` ` `  `    ``// Variable to represent which row of ` `    ``// matrix is current row. ` `    ``int` `currRow = 0; ` ` `  `    ``// For a particular value of i and j, ` `    ``// len[currRow][j] stores length of longest ` `    ``// common substring in string X[0..i] and Y[0..j]. ` `    ``for` `(``int` `i = 0; i <= m; i++) { ` `        ``for` `(``int` `j = 0; j <= n; j++) { ` `            ``if` `(i == 0 || j == 0) { ` `                ``len[currRow][j] = 0; ` `            ``} ` `            ``else` `if` `(X[i - 1] == Y[j - 1]) { ` `                ``len[currRow][j] = len[1 - currRow][j - 1] + 1; ` `                ``if` `(len[currRow][j] > result) { ` `                    ``result = len[currRow][j]; ` `                    ``end = i - 1; ` `                ``} ` `            ``} ` `            ``else` `{ ` `                ``len[currRow][j] = 0; ` `            ``} ` `        ``} ` ` `  `        ``// Make current row as previous row and ` `        ``// previous row as new current row. ` `        ``currRow = 1 - currRow; ` `    ``} ` ` `  `    ``// If there is no common substring, print -1. ` `    ``if` `(result == 0) { ` `        ``return` `"-1"``; ` `    ``} ` ` `  `    ``// Longest common substring is from index ` `    ``// end - result + 1 to index end in X. ` `    ``return` `X.substr(end - result + 1, result); ` `} ` `// Driver Code ` `int` `main() ` `{ ` `    ``string X = ``"GeeksforGeeks"``; ` `    ``string Y = ``"GeeksQuiz"``; ` `    ``// function call ` `    ``cout << LCSubStr(X, Y); ` `    ``return` `0; ` `} `

## Java

 `// Space optimized Java implementation to print  ` `// longest common substring. ` ` `  `public` `class` `GFG { ` ` `  `// Function to find longest common substring.  ` `    ``static` `String LCSubStr(String X, String Y) { ` `        ``// Find length of both the Strings.  ` `        ``int` `m = X.length(); ` `        ``int` `n = Y.length(); ` ` `  `        ``// Variable to store length of longest  ` `        ``// common subString.  ` `        ``int` `result = ``0``; ` ` `  `        ``// Variable to store ending point of  ` `        ``// longest common subString in X.  ` `        ``int` `end = ``0``; ` ` `  `        ``// Matrix to store result of two  ` `        ``// consecutive rows at a time.  ` `        ``int` `len[][] = ``new` `int``[``2``][m]; ` ` `  `        ``// Variable to represent which row of  ` `        ``// matrix is current row.  ` `        ``int` `currRow = ``0``; ` ` `  `        ``// For a particular value of i and j,  ` `        ``// len[currRow][j] stores length of longest  ` `        ``// common subString in String X[0..i] and Y[0..j].  ` `        ``for` `(``int` `i = ``0``; i <= m; i++) { ` `            ``for` `(``int` `j = ``0``; j <= n; j++) { ` `                ``if` `(i == ``0` `|| j == ``0``) { ` `                    ``len[currRow][j] = ``0``; ` `                ``} ``else` `if` `(X.charAt(i - ``1``) == Y.charAt(j - ``1``)) { ` `                    ``len[currRow][j] = len[``1` `- currRow][j - ``1``] + ``1``; ` `                    ``if` `(len[currRow][j] > result) { ` `                        ``result = len[currRow][j]; ` `                        ``end = i - ``1``; ` `                    ``} ` `                ``} ``else` `{ ` `                    ``len[currRow][j] = ``0``; ` `                ``} ` `            ``} ` ` `  `            ``// Make current row as previous row and  ` `            ``// previous row as new current row.  ` `            ``currRow = ``1` `- currRow; ` `        ``} ` ` `  `        ``// If there is no common subString, print -1.  ` `        ``if` `(result == ``0``) { ` `            ``return` `"-1"``; ` `        ``} ` ` `  `        ``// Longest common subString is from index  ` `        ``// end - result + 1 to index end in X.  ` `        ``return` `X.substring(end - result + ``1``, result); ` `    ``} ` `     `  `    ``// Driver Code  ` `    ``public` `static` `void` `main(String[] args) { ` `        ``String X = ``"GeeksforGeeks"``; ` `        ``String Y = ``"GeeksQuiz"``; ` `        ``// function call  ` `        ``System.out.println(LCSubStr(X, Y)); ` ` `  `    ``} ` ` `  `} ` `// This code is contributed by PrinciRaj1992 `

## C#

 `using` `System; ` `// Space optimized Java implementation to print  ` `// longest common substring. ` `  `  `public` `class` `GFG { ` `  `  `// Function to find longest common substring.  ` `    ``static` `string` `LCSubStr(``string` `X, ``string` `Y) { ` `        ``// Find length of both the Strings.  ` `        ``int` `m = X.Length; ` `        ``int` `n = Y.Length; ` `  `  `        ``// Variable to store length of longest  ` `        ``// common subString.  ` `        ``int` `result = 0; ` `  `  `        ``// Variable to store ending point of  ` `        ``// longest common subString in X.  ` `        ``int` `end = 0; ` `  `  `        ``// Matrix to store result of two  ` `        ``// consecutive rows at a time.  ` `        ``int``[,] len = ``new` `int``[2,m]; ` `  `  `        ``// Variable to represent which row of  ` `        ``// matrix is current row.  ` `        ``int` `currRow = 0; ` `  `  `        ``// For a particular value of i and j,  ` `        ``// len[currRow][j] stores length of longest  ` `        ``// common subString in String X[0..i] and Y[0..j].  ` `        ``for` `(``int` `i = 0; i <= m; i++) { ` `            ``for` `(``int` `j = 0; j <= n; j++) { ` `                ``if` `(i == 0 || j == 0) { ` `                    ``len[currRow,j] = 0; ` `                ``} ``else` `if` `(X[i - 1] == Y[j - 1]) { ` `                    ``len[currRow,j] = len[1 - currRow,j - 1] + 1; ` `                    ``if` `(len[currRow,j] > result) { ` `                        ``result = len[currRow,j]; ` `                        ``end = i - 1; ` `                    ``} ` `                ``} ``else` `{ ` `                    ``len[currRow,j] = 0; ` `                ``} ` `            ``} ` `  `  `            ``// Make current row as previous row and  ` `            ``// previous row as new current row.  ` `            ``currRow = 1 - currRow; ` `        ``} ` `  `  `        ``// If there is no common subString, print -1.  ` `        ``if` `(result == 0) { ` `            ``return` `"-1"``; ` `        ``} ` `  `  `        ``// Longest common subString is from index  ` `        ``// end - result + 1 to index end in X.  ` `        ``return` `X.Substring(end - result + 1, result); ` `    ``} ` `      `  `    ``// Driver Code  ` `    ``public` `static` `void` `Main() { ` `        ``string` `X = ``"GeeksforGeeks"``; ` `        ``string` `Y = ``"GeeksQuiz"``; ` `        ``// function call  ` `        ``Console.Write(LCSubStr(X, Y)); ` `  `  `    ``} ` `  `  `} `

Output:

```Geeks
```

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

This approach has been suggested by nik1996.
This article is contributed by Ayush Jauhari. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

My Personal Notes arrow_drop_up

Article Tags :
Practice Tags :

6

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.