📜  LCS的空间优化解决方案

📅  最后修改于: 2021-04-30 03:40:13             🧑  作者: Mango

给定两个字符串,找到两个字符串存在的最长子序列的长度。

例子:
输入序列“ 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)