给定两个字符串,找到两个字符串存在的最长子序列的长度。
例子:
输入序列“ ABCDGH ”和“ AEDFHR ”的LCS是长度为3的“ ADH ”。
输入序列“ AGGTAB ”和“ GXTXAYB ”的LCS是长度为4的“ GTAB ”。
我们已经讨论了用于LCS的典型的基于动态编程的解决方案。我们可以优化lcs问题所使用的空间。我们知道LCS问题的递归关系是
/* Returns length of LCS for X[0..m-1], Y[0..n-1] */
int lcs(string &X, string &Y)
{
int m = X.length(), n = Y.length();
int L[m+1][n+1];
/* Following steps build L[m+1][n+1] in bottom up
fashion. Note that L[i][j] contains length of
LCS of X[0..i-1] and Y[0..j-1] */
for (int i=0; i<=m; i++)
{
for (int j=0; j<=n; j++)
{
if (i == 0 || j == 0)
L[i][j] = 0;
else if (X[i-1] == Y[j-1])
L[i][j] = L[i-1][j-1] + 1;
else
L[i][j] = max(L[i-1][j], L[i][j-1]);
}
}
/* L[m][n] contains length of LCS for X[0..n-1] and
Y[0..m-1] */
return L[m][n];
}
如何找到O(n)辅助空间中LCS的长度?
我们强烈建议您单击此处并进行实践,然后再继续解决方案。
上述简单实现中的一个重要观察结果是,仅在外循环的每次迭代中,我们都需要前一行所有列中的值。因此,无需将所有行都存储在DP矩阵中,我们可以一次存储两行并使用它们,这样用过的空间将从L [m + 1] [n + 1]减少到L [2 ] [n + 1]。以下是上述想法的实现。
C++
// Space optimized C++ implementation
// of LCS problem
#include
using namespace std;
// Returns length of LCS
// for X[0..m-1], Y[0..n-1]
int lcs(string &X, string &Y)
{
// Find lengths of two strings
int m = X.length(), n = Y.length();
int L[2][n + 1];
// Binary index, used to
// index current row and
// previous row.
bool bi;
for (int i = 0; i <= m; i++)
{
// Compute current
// binary index
bi = i & 1;
for (int j = 0; j <= n; j++)
{
if (i == 0 || j == 0)
L[bi][j] = 0;
else if (X[i-1] == Y[j-1])
L[bi][j] = L[1 - bi][j - 1] + 1;
else
L[bi][j] = max(L[1 - bi][j],
L[bi][j - 1]);
}
}
// Last filled entry contains
// length of LCS
// for X[0..n-1] and Y[0..m-1]
return L[bi][n];
}
// Driver code
int main()
{
string X = "AGGTAB";
string Y = "GXTXAYB";
printf("Length of LCS is %d\n", lcs(X, Y));
return 0;
}
Java
// Java Code for A Space Optimized
// Solution of LCS
class GFG {
// Returns length of LCS
// for X[0..m - 1],
// Y[0..n - 1]
public static int lcs(String X,
String Y)
{
// Find lengths of two strings
int m = X.length(), n = Y.length();
int L[][] = new int[2][n+1];
// Binary index, used to index
// current row and previous row.
int bi=0;
for (int i = 0; i <= m; i++)
{
// Compute current binary index
bi = i & 1;
for (int j = 0; j <= n; j++)
{
if (i == 0 || j == 0)
L[bi][j] = 0;
else if (X.charAt(i - 1) ==
Y.charAt(j - 1))
L[bi][j] = L[1 - bi][j - 1] + 1;
else
L[bi][j] = Math.max(L[1 - bi][j],
L[bi][j - 1]);
}
}
// Last filled entry contains length of
// LCS for X[0..n-1] and Y[0..m-1]
return L[bi][n];
}
// Driver Code
public static void main(String[] args)
{
String X = "AGGTAB";
String Y = "GXTXAYB";
System.out.println("Length of LCS is " +
lcs(X, Y));
}
}
// This code is contributed by Arnav Kr. Mandal.
Python3
# Space optimized Python
# implementation of LCS problem
# Returns length of LCS for
# X[0..m-1], Y[0..n-1]
def lcs(X, Y):
# Find lengths of two strings
m = len(X)
n = len(Y)
L = [[0 for i in range(n+1)] for j in range(2)]
# Binary index, used to index current row and
# previous row.
bi = bool
for i in range(m):
# Compute current binary index
bi = i&1
for j in range(n+1):
if (i == 0 or j == 0):
L[bi][j] = 0
elif (X[i] == Y[j - 1]):
L[bi][j] = L[1 - bi][j - 1] + 1
else:
L[bi][j] = max(L[1 - bi][j],
L[bi][j - 1])
# Last filled entry contains length of LCS
# for X[0..n-1] and Y[0..m-1]
return L[bi][n]
# Driver Code
X = "AGGTAB"
Y = "GXTXAYB"
print("Length of LCS is", lcs(X, Y))
# This code is contributed by Soumen Ghosh.
C#
// C# Code for A Space
// Optimized Solution of LCS
using System;
class GFG
{
// Returns length of LCS
// for X[0..m - 1],
// Y[0..n - 1]
public static int lcs(string X,
string Y)
{
// Find lengths of
// two strings
int m = X.Length, n = Y.Length;
int [,]L = new int[2, n + 1];
// Binary index, used to
// index current row and
// previous row.
int bi = 0;
for (int i = 0; i <= m; i++)
{
// Compute current
// binary index
bi = i & 1;
for (int j = 0; j <= n; j++)
{
if (i == 0 || j == 0)
L[bi, j] = 0;
else if (X[i - 1] == Y[j - 1])
L[bi, j] = L[1 - bi,
j - 1] + 1;
else
L[bi, j] = Math.Max(L[1 - bi, j],
L[bi, j - 1]);
}
}
// Last filled entry contains
// length of LCS for X[0..n-1]
// and Y[0..m-1]
return L[bi, n];
}
// Driver Code
public static void Main()
{
string X = "AGGTAB";
string Y = "GXTXAYB";
Console.Write("Length of LCS is " +
lcs(X, Y));
}
}
// This code is contributed
// by shiv_bhakt.
PHP
输出:
Length of LCS is 4
时间复杂度: O(m * n)
辅助空间: O(n)