给定两个字符串“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
Javascript
输出 :
5
时间复杂度: O(m*n)
辅助空间: O(n)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。