给定两个字符串“ X”和“ Y”,找到最长的公共子字符串的长度。预期的空间复杂度是线性的。
例子 :
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.
我们已经讨论了针对最长公共子字符串的基于动态编程的解决方案。解决方案使用的辅助空间为O(m * n),其中m和n是字符串X和Y的长度。解决方案使用的空间可以减小为O(2 * n)。
假设我们在mat [i] [j]的位置。现在,如果X [i-1] == Y [j-1],则将mat [i-1] [j-1]的值添加到结果中。也就是说,我们将前一行的值相加,并且永远不会使用前一行之下的所有其他行的值。因此,一次我们仅使用两个连续的行。此观察结果可用于减少找到最长的公共子字符串的长度所需的空间。
代替创建大小为m * n的矩阵,我们创建大小为2 * n的矩阵。变量currRow用于表示该矩阵的第0行或第1行当前用于查找长度。对于字符串X的长度为零的情况,最初将第0行用作当前行。在每次迭代结束时,将当前行设置为上一行,将前一行设置为新的当前行。
C++
// Space optimized CPP implementation of longest
// common substring.
#include
using namespace std;
// Function to find longest common substring.
int 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;
// Matrix to store result of two
// consecutive rows at a time.
int len[2][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;
result = max(result, len[currRow][j]);
}
else {
len[currRow][j] = 0;
}
}
// Make current row as previous row and previous
// row as new current row.
currRow = 1 - currRow;
}
return result;
}
int main()
{
string X = "GeeksforGeeks";
string Y = "GeeksQuiz";
cout << LCSubStr(X, Y);
return 0;
}
Java
// Space optimized CPP implementation of
// longest common substring.
import java.io.*;
import java.util.*;
public class GFG {
// Function to find longest
// common substring.
static int 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;
// Matrix to store result of two
// consecutive rows at a time.
int [][]len = new int[2][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.charAt(i - 1) ==
Y.charAt(j - 1))
{
len[currRow][j] =
len[(1 - currRow)][(j - 1)]
+ 1;
result = Math.max(result,
len[currRow][j]);
}
else
{
len[currRow][j] = 0;
}
}
// Make current row as previous
// row and previous row as
// new current row.
currRow = 1 - currRow;
}
return result;
}
// Driver Code
public static void main(String args[])
{
String X = "GeeksforGeeks";
String Y = "GeeksQuiz";
System.out.print(LCSubStr(X, Y));
}
}
// This code is contributed by
// Manish Shaw (manishshaw1)
Python3
# Space optimized Python3 implementation
# of longest common substring.
import numpy as np
# Function to find longest common substring.
def LCSubStr(X, Y) :
# Find length of both the strings.
m = len(X)
n = len(Y)
# Variable to store length of
# longest common substring.
result = 0
# Matrix to store result of two
# consecutive rows at a time.
len_mat = np.zeros((2, n))
# Variable to represent which row
# of matrix is current row.
currRow = 0
# For a particular value of i and j,
# len_mat[currRow][j] stores length of
# longest common substring in string
# X[0..i] and Y[0..j].
for i in range(m) :
for j in range(n) :
if (i == 0 | j == 0) :
len_mat[currRow][j] = 0
elif (X[i - 1] == Y[j - 1]) :
len_mat[currRow][j] = len_mat[1 - currRow][j - 1] + 1
result = max(result, len_mat[currRow][j])
else :
len_mat[currRow][j] = 0
# Make current row as previous row and
# previous row as new current row.
currRow = 1 - currRow
return result
# Driver Code
if __name__ == "__main__" :
X = "GeeksforGeeks"
Y = "GeeksQuiz"
print(LCSubStr(X, Y))
# This code is contributed by Ryuga
C#
// Space optimized C# implementation
// of longest common substring.
using System;
using System.Collections.Generic;
class GFG {
// Function to find longest
// common substring.
static int 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;
// Matrix to store result of two
// consecutive rows at a time.
int [,]len = new int[2,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;
result = Math.Max(result, len[currRow, j]);
}
else
{
len[currRow,j] = 0;
}
}
// Make current row as previous
// row and previous row as
// new current row.
currRow = 1 - currRow;
}
return result;
}
// Driver Code
public static void Main()
{
string X = "GeeksforGeeks";
string Y = "GeeksQuiz";
Console.Write(LCSubStr(X, Y));
}
}
// This code is contributed by
// Manish Shaw (manishshaw1)
PHP
输出 :
5
时间复杂度: O(m * n)
辅助空间: O(n)