Самая длинная общая подстрока | ДП-29
Для двух строк «X» и «Y» найдите длину самой длинной общей подстроки.
Примеры :
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 : 4
Explanation:
The longest common substring is “abcd” and is of length 4.Input : X = “zxabcdezy”, y = “yzabcdezx”
Output : 6
Explanation:
The longest common substring is “abcdez” and is of length 6.

Подход:
 Пусть m и n - длины первой и второй строк соответственно.
 Простое решение состоит в том, чтобы поочередно рассмотреть все подстроки первой строки и для каждой подстроки проверить, является ли она подстрокой во второй строке. Следите за подстрокой максимальной длины. Будет O (m ^ 2) подстрок, и мы сможем определить, является ли строка подстрокой в другой строке за время O (n) (см. Это). Таким образом, общая временная сложность этого метода будет O (n * m 2 )
 Динамическое программирование можно использовать для поиска самой длинной общей подстроки за время O (m * n). Идея состоит в том, чтобы найти длину самого длинного общего суффикса для всех подстрок обеих строк и сохранить эти длины в таблице.
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 <iostream>#include <string.h>usingnamespacestd;/* Returns length of longest   common substring of X[0..m-1]   and Y[0..n-1] */intLCSubStr(char* X, char* Y, intm, intn){    // 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].    intLCSuff[m + 1][n + 1];    intresult = 0; // To store length of the                    // longest common substring    /* Following steps build LCSuff[m+1][n+1] in        bottom up fashion. */    for(inti = 0; i <= m; i++)    {        for(intj = 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;            elseif(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;        }    }    returnresult;}// Driver codeintmain(){    charX[] = "OldSite:GeeksforGeeks.org";    charY[] = "NewSite:GeeksQuiz.com";    intm = strlen(X);    intn = strlen(Y);    cout << "Length of Longest Common Substring is "         << LCSubStr(X, Y, m, n);    return0;} | 
Java
| //  Java implementation of// finding length of longest// Common substring using// Dynamic ProgrammingclassGFG {    /*       Returns length of longest common substring       of X[0..m-1] and Y[0..n-1]    */    staticintLCSubStr(charX[], charY[],                         intm, intn)    {        // 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        intLCStuff[][] = newint[m + 1][n + 1];              // To store length of the longest        // common substring        intresult = 0;        // Following steps build        // LCSuff[m+1][n+1] in bottom up fashion        for(inti = 0; i <= m; i++)        {            for(intj = 0; j <= n; j++)            {                if(i == 0|| j == 0)                    LCStuff[i][j] = 0;                elseif(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;            }        }        returnresult;    }    // Driver Code    publicstaticvoidmain(String[] args)    {        String X = "OldSite:GeeksforGeeks.org";        String Y = "NewSite:GeeksQuiz.com";        intm = X.length();        intn = Y.length();        System.out.println(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]defLCSubStr(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 =[[0fork inrange(n+1)] forl inrange(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    fori inrange(m +1):        forj inrange(n +1):            if(i ==0orj ==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    returnresult# Driver CodeX ="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 ProgrammingusingSystem;classGFG {    // Returns length of longest common    // substring of X[0..m-1] and Y[0..n-1]    staticintLCSubStr(stringX, stringY, intm, intn)    {        // 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 = newint[m + 1, n + 1];        // To store length of the longest common        // substring        intresult = 0;        // Following steps build LCSuff[m+1][n+1]        // in bottom up fashion        for(inti = 0; i <= m; i++)        {            for(intj = 0; j <= n; j++)            {                if(i == 0 || j == 0)                    LCStuff[i, j] = 0;                elseif(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;            }        }        returnresult;    }    // Driver Code    publicstaticvoidMain()    {        String X = "OldSite:GeeksforGeeks.org";        String Y = "NewSite:GeeksQuiz.com";        intm = X.Length;        intn = Y.Length;        Console.Write("Length of Longest Common"                      + " Substring is "                      + LCSubStr(X, Y, m, n));    }}// This code is contributed by Sam007. | 
PHP
| <?php// Dynamic Programming solution to find// length of the longest common substring// Returns length of longest common// substring of X[0..m-1] and Y[0..n-1]functionLCSubStr($X, $Y, $m, $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    $LCSuff= array_fill(0, $m+ 1,              array_fill(0, $n+ 1, NULL));    $result= 0; // To store length of the                 // longest common substring    // Following steps build LCSuff[m+1][n+1]    // in bottom up fashion.    for($i= 0; $i<= $m; $i++)    {        for($j= 0; $j<= $n; $j++)        {            if($i== 0 || $j== 0)                $LCSuff[$i][$j] = 0;            elseif($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= strlen($X);$n= strlen($Y);echo"Length of Longest Common Substring is ".                      LCSubStr($X, $Y, $m, $n);                      // This code is contributed by ita_c?> | 
Length of Longest Common Substring is 10
Сложность времени: O (m * n)
 Вспомогательное пространство: O (m * n)
Другой подход: (Оптимизированный по пространству подход).
 В вышеупомянутом подходе мы используем только последнюю строку двумерного массива, поэтому мы можем оптимизировать пространство, используя
 двумерный массив размерности 2 * (min (n, m)).
Ниже представлена реализация описанного выше подхода:
Сложность времени: O (n * m)
 Вспомогательное пространство: O (min (m, n))
Another approach: (Using recursion) 
Here is the recursive solution of above approach. 
C++
| // C++ program using to find length of the// longest common substring  recursion#include <iostream>usingnamespacestd;string X, Y;// Returns length of function f// or longest common substring// of X[0..m-1] and Y[0..n-1]intlcs(inti, intj, intcount){    if(i == 0 || j == 0)        returncount;    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)));    returncount;}// Driver codeintmain(){    intn, m;    X = "abcdxyz";    Y = "xyzabcd";    n = X.size();    m = Y.size();РЕКОМЕНДУЕМЫЕ СТАТЬИ |