📜  找到 S 的子序列和 T 的子序列的相等对

📅  最后修改于: 2021-09-22 09:56:14             🧑  作者: Mango

给定两个大小分别为NM 的数组S[]T[] 。任务是找到内容相同的S[] 的子序列和T[] 的子序列对。答案可能非常大。因此,打印答案模10 9 + 7
例子:

方法:DP [i] [j]是方法来创建仅使用S [i元素]T []的第j个元素,使得所述子序列是相同的子序列的数量和i元件S[]T[] 的j元素是子序列的一部分。
基本上,DP [i] [j]是答案的问题,如果仅S []T的第j个元素的第一i个元素[]被考虑。如果S [I]!= T [j]的然后DP [i] [j] = 0,因为没有子序列将通过使用Si元素[]和第j的T元素结束[]。如果S[i] = T[j]那么dp[i][j] = ∑ k=1 i-1l=1 j-1 dp[k][l] + 1因为S[]的前一个索引可以是任何索引≤ i并且T[]的前一个索引可以是任何索引≤ j
作为基本情况, dp[0][0] = 1 。这表示不采用任何元素的情况。它的运行时间是O(N 2 * M 2 )但我们可以通过预先计算总和来加快速度。
sum[i][j] = ∑ k=1 il=1 j dp[k][l]这是 dp 数组的二维前缀和。 sum[i][j] = sum[i – 1][j] + sum[i][j – 1] – sum[i – 1][j – 1] + dp[i][j] 。使用sum[i][j] ,现在可以在O(1) 中计算每个状态dp[i][j]
由于有N * M个状态,运行时间将为O(N * M)
下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
 
#define mod (int)(1e9 + 7)
 
// Function to return the pairs of subsequences
// from S[] and subsequences from T[] such
// that both have the same content
int subsequence(int S[], int T[], int n, int m)
{
 
    // Create dp array
    int dp[n + 1][m + 1];
 
    // Base values
    for (int i = 0; i <= n; i++)
        dp[i][0] = 1;
 
    // Base values
    for (int j = 0; j <= m; j++)
        dp[0][j] = 1;
 
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
 
            // Keep previous dp value
            dp[i][j] = dp[i - 1][j]
                       + dp[i][j - 1]
                       - dp[i - 1][j - 1];
 
            // If both elements are same
            if (S[i - 1] == T[j - 1])
                dp[i][j] += dp[i - 1][j - 1];
 
            dp[i][j] += mod;
            dp[i][j] %= mod;
        }
    }
 
    // Return the required answer
    return dp[n][m];
}
 
// Driver code
int main()
{
    int S[] = { 1, 1 };
    int n = sizeof(S) / sizeof(S[0]);
 
    int T[] = { 1, 1 };
    int m = sizeof(T) / sizeof(T[0]);
 
    cout << subsequence(S, T, n, m);
 
    return 0;
}


Java
// Java implementation of the approach
import java.util.*;
 
class GFG
{
 
// Function to return the pairs of subsequences
// from S[] and subsequences from T[] such
// that both have the same content
static int subsequence(int[] S, int[] T,
                       int n, int m)
{
 
    // Create dp array
    int [][] dp = new int[n + 1][m + 1];
    int mod = 1000000007;
 
    // Base values
    for (int i = 0; i <= n; i++)
        dp[i][0] = 1;
 
    // Base values
    for (int j = 0; j <= m; j++)
        dp[0][j] = 1;
 
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= m; ++j)
        {
 
            // Keep previous dp value
            dp[i][j] = dp[i - 1][j] +
                       dp[i][j - 1] -
                       dp[i - 1][j - 1];
 
            // If both elements are same
            if (S[i - 1] == T[j - 1])
                dp[i][j] += dp[i - 1][j - 1];
 
            dp[i][j] += mod;
            dp[i][j] %= mod;
        }
    }
 
    // Return the required answer
    return dp[n][m];
}
 
 
// Driver code
public static void main(String []args)
{
    int S[] = { 1, 1 };
    int n = S.length;
 
    int T[] = { 1, 1 };
    int m = T.length;
 
    System.out.println(subsequence(S, T, n, m));
}
}
 
// This code is contributed by Sanjit Prasad


Python3
# Python3 implementation of the approach
import numpy as np
 
mod = int(1e9 + 7)
 
# Function to return the pairs of subsequences
# from S[] and subsequences from T[] such
# that both have the same content
def subsequence(S, T, n, m) :
 
    # Create dp array
    dp = np.zeros((n + 1, m + 1));
 
    # Base values
    for i in range(n + 1) :
        dp[i][0] = 1;
 
    # Base values
    for j in range(m + 1) :
        dp[0][j] = 1;
 
    for i in range(1, n + 1) :
        for j in range(1, m + 1) :
 
            # Keep previous dp value
            dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - \
                       dp[i - 1][j - 1];
 
            # If both elements are same
            if (S[i - 1] == T[j - 1]) :
                dp[i][j] += dp[i - 1][j - 1];
 
            dp[i][j] += mod;
            dp[i][j] %= mod;
 
    # Return the required answer
    return dp[n][m];
 
# Driver code
if __name__ == "__main__" :
 
    S = [ 1, 1 ];
    n = len(S);
 
    T = [ 1, 1 ];
    m = len(T);
 
    print(subsequence(S, T, n, m));
 
# This code is contributed by kanugargng


C#
// C# implementation of the approach
using System;
 
class GFG
{
 
    // Function to return the pairs of subsequences
    // from S[] and subsequences from T[] such
    // that both have the same content
    static int subsequence(int[] S, int[] T,
                           int n, int m)
    {
     
        // Create dp array
        int [,] dp = new int[n + 1, m + 1];
        int mod = 1000000007;
     
        // Base values
        for (int i = 0; i <= n; i++)
            dp[i, 0] = 1;
     
        // Base values
        for (int j = 0; j <= m; j++)
            dp[0, j] = 1;
     
        for (int i = 1; i <= n; ++i)
        {
            for (int j = 1; j <= m; ++j)
            {
     
                // Keep previous dp value
                dp[i, j] = dp[i - 1, j] +
                           dp[i, j - 1] -
                           dp[i - 1, j - 1];
     
                // If both elements are same
                if (S[i - 1] == T[j - 1])
                    dp[i, j] += dp[i - 1, j - 1];
     
                dp[i, j] += mod;
                dp[i, j] %= mod;
            }
        }
     
        // Return the required answer
        return dp[n, m];
    }
     
    // Driver code
    public static void Main()
    {
        int []S = { 1, 1 };
        int n = S.Length;
     
        int []T = { 1, 1 };
        int m = T.Length;
     
        Console.WriteLine(subsequence(S, T, n, m));
    }
}
 
// This code is contributed by AnkitRai01


Javascript


输出:

6

时间复杂度:O(N*M)
辅助空间:O(N*M)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程