Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Find the equal pairs of subsequence of S and subsequence of T

  • Last Updated : 03 Jun, 2021

Given two arrays S[] and T[] of size N and M respectively. The task is to find the pairs of subsequences of S[] and subsequences of T[] which are the same in content. Answer could be very large. So, print the answer modulo 109 + 7.
Examples: 
 

Input: S[] = {1, 1}, T[] = {1, 1} 
Output:
Subsequences of S[] are {}, {1}, {1} and {1, 1}. 
Subsequences of T[] are {}, {1}, {1} and {1, 1}. 
All the valid pairs are ({}, {}), ({1}, {1}), ({1}, {1}), 
({1}, {1}), ({1}, {1}) and ({1, 1}, {1, 1}).
Input: S[] = {1, 3}, T[] = {3, 1} 
Output:
 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

 



Approach: Let dp[i][j] be the number of ways to create subsequences only using the first i elements of S[] and the first j elements of T[] such that the subsequences are the same and the ith element of S[] and the jth element of T[] are part of the subsequences. 
Basically, dp[i][j] is the answer to the problem if only the first i elements of S[] and the first j elements of T[] are considered. If S[i] != T[j] then dp[i][j] = 0 because no subsequence will end by using the ith element of S[] and the jth element of T[]. If S[i] = T[j] then dp[i][j] = ∑k=1i-1l=1j-1 dp[k][l] + 1 because the previous index of S[] can be any index ≤ i and the previous index of T[] can be any index ≤ j
As a base case, dp[0][0] = 1. This represents the case where no element is taken. The runtime of this is O(N2 * M2) but we can speed this up by precomputing the sums. 
Let sum[i][j] = ∑k=1il=1jdp[k][l] which is a 2D prefix sum of the dp array. sum[i][j] = sum[i – 1][j] + sum[i][j – 1] – sum[i – 1][j – 1] + dp[i][j]. With sum[i][j], each state dp[i][j] can now be calculated in O(1)
Since there are N * M states, the runtime will be O(N * M).
Below is the implementation of the above approach: 
 

C++




// C++ implementation of the approach
#include <bits/stdc++.h>
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




<script>
 
// JavaScript implementation of the approach
 
 
let mod = 1e9 + 7;
 
// Function to return the pairs of subsequences
// from S[] and subsequences from T[] such
// that both have the same content
function subsequence(S, T, n, m) {
 
    // Create dp array
    let dp = new Array()
 
    for (let i = 0; i < n + 1; i++) {
        let temp = [];
        for (let j = 0; j < m + 1; j++) {
            temp.push([])
        }
        dp.push(temp)
    }
 
    // Base values
    for (let i = 0; i <= n; i++)
        dp[i][0] = 1;
 
    // Base values
    for (let j = 0; j <= m; j++)
        dp[0][j] = 1;
 
    for (let i = 1; i <= n; ++i) {
        for (let 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
 
let S = [1, 1];
let n = S.length;
 
let T = [1, 1];
let m = T.length;
 
document.write(subsequence(S, T, n, m));
 
</script>
Output: 
6

 

Time Complexity: O( N*M )
Auxiliary Space: O(N*M )




My Personal Notes arrow_drop_up
Recommended Articles
Page :