Open In App

Find the longest subsequence of a string that is a substring of another string

Last Updated : 06 Jul, 2021
Comments
Improve
Suggest changes
Like Article
Like
Report

Given two strings X and Y consisting of N and M characters, the task is to find the longest subsequence of a string X which is a substring of the string Y.

Examples:

Input: X = "ABCD", Y = "ACDBDCD"
Output: ACD
Explanation:
"ACD" is longest subsequence of X which is substring of Y.

Input: X = A, Y = A
Output: A

Naive Approach: The simplest approach to solve the given problem is to find all the subsequences of the given string X and print that subsequence among all the generated subsequences which is of maximum length and is a substring of Y.

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

Efficient Approach: The above approach can also be optimized by using Dynamic Programming. The idea is to create a 2D array, dp[][] of dimensions (N + 1)*(M + 1) and the state dp[i][j] is maximum length of subsequence of X[0, i] which is substring of Y[0, j]. Follow the steps below to solve the problem: 

  • Create a 2D array, dp[][] of size N+1 rows and M+1 columns.
  • Initialize the first row and the first column of the matrix with 0.
  • Fill all the remaining rows as follows:
    • If the value of X[i - 1] is equal to the value of Y[j - 1], then update the value of dp[i][j] to (1 + dp[i - 1][j - 1]).
    • Otherwise, update the value of dp[i][j] to dp[i - 1][j].
  • Store the maximum length of the required sequence in a variable len by iterating the last row in the matrix and store the row and column index of the maximum cell value in variables i and j respectively.
  • Create a variable, say res to store the resultant string and backtrack from the maximum cell value.
  • Iterate until the value of len is greater than 0, and perform the following steps:
    • If the value of X[i - 1] is equal to the value of Y[j - 1], then append X[i - 1] to res and decrement the value of len, i and j by 1.
    • Otherwise, decrement the value of i by 1.
  • After completing the above steps, print the string res as the result.

Below is the implementation of the above approach:

C++
// C++ program for the above approach 
#include <bits/stdc++.h>
using namespace std;

// Function to find the longest
// subsequence that matches with
// the substring of other string
string longestSubsequence(string X, string Y)
{
    
    // Stores the lengths of strings
    // X and Y
    int n = X.size();
    int m = Y.size();

    // Create a matrix
    vector<vector<int>> mat(n + 1, vector<int>(m + 1));
    
    // Initialize the matrix
    for(int i = 0; i < n + 1; i++) 
    {
        for(int j = 0; j < m + 1; j++) 
        {
            if (i == 0 || j == 0)
                mat[i][j] = 0;
        }
    }

    // Fill all the remaining rows
    for(int i = 1; i < n + 1; i++) 
    {
        for(int j = 1; j < m + 1; j++) 
        {
            
            // If the characters are equal
            if (X[i - 1] == Y[j - 1])
            {
                mat[i][j] = 1 + mat[i - 1][j - 1];
            }

            // If not equal, then
            // just move to next
            // in subsequence string
            else 
            {
                mat[i][j] = mat[i - 1][j];
            }
        }
    }

    // Find maximum length of the
    // longest subsequence matching
    // substring of other string
    int len = 0, col = 0;

    // Iterate through the last
    // row of matrix
    for(int i = 0; i < m + 1; i++)
    {
        if (mat[n][i] > len)
        {
            len = mat[n][i];
            col = i;
        }
    }

    // Store the required string
    string res = "";
    int i = n;
    int j = col;

    // Backtrack from the cell
    while (len > 0) 
    {
        
        // If equal, then add the
        // character to res string
        if (X[i - 1] == Y[j - 1]) 
        {
            res = X[i - 1] + res;
            i--;
            j--;
            len--;
        }
        else
        {
            i--;
        }
    }

    // Return the required string
    return res;
}

// Driver code
int main()
{
    string X = "ABCD";
    string Y = "ACDBDCD";
    
    cout << (longestSubsequence(X, Y));
    
    return 0;
}

// This code is contributed by mohit kumar 29
Java
// Java program for the above approach

class GFG {

    // Function to find the longest
    // subsequence that matches with
    // the substring of other string
    public static String longestSubsequence(
        String X, String Y)
    {

        // Stores the lengths of strings
        // X and Y
        int n = X.length();
        int m = Y.length();

        // Create a matrix
        int[][] mat = new int[n + 1][m + 1];

        // Initialize the matrix
        for (int i = 0; i < n + 1; i++) {
            for (int j = 0; j < m + 1; j++) {
                if (i == 0 || j == 0)
                    mat[i][j] = 0;
            }
        }

        // Fill all the remaining rows
        for (int i = 1;
             i < n + 1; i++) {

            for (int j = 1;
                 j < m + 1; j++) {

                // If the characters are equal
                if (X.charAt(i - 1)
                    == Y.charAt(j - 1)) {
                    mat[i][j] = 1
                                + mat[i - 1][j - 1];
                }

                // If not equal, then
                // just move to next
                // in subsequence string
                else {
                    mat[i][j] = mat[i - 1][j];
                }
            }
        }

        // Find maximum length of the
        // longest subsequence matching
        // substring of other string
        int len = 0, col = 0;

        // Iterate through the last
        // row of matrix
        for (int i = 0; i < m + 1; i++) {

            if (mat[n][i] > len) {
                len = mat[n][i];
                col = i;
            }
        }

        // Store the required string
        String res = "";
        int i = n;
        int j = col;

        // Backtrack from the cell
        while (len > 0) {

            // If equal, then add the
            // character to res string
            if (X.charAt(i - 1)
                == Y.charAt(j - 1)) {

                res = X.charAt(i - 1) + res;
                i--;
                j--;
                len--;
            }
            else {
                i--;
            }
        }

        // Return the required string
        return res;
    }

    // Driver Code
    public static void main(String args[])
    {
        String X = "ABCD";
        String Y = "ACDBDCD";
        System.out.println(
            longestSubsequence(X, Y));
    }
}
Python3
# Python3 program for the above approach

# Function to find the longest
# subsequence that matches with
# the substring of other string
def longestSubsequence(X, Y):
    
    # Stores the lengths of strings
    # X and Y
    n = len(X)
    m = len(Y)

    # Create a matrix
    mat = [[0 for i in range(m + 1)] 
              for j in range(n + 1)]
              
    # Initialize the matrix
    for i in range(0, n + 1):
        for j in range(0, m + 1):
            if (i == 0 or j == 0):
                mat[i][j] = 0

    # Fill all the remaining rows
    for i in range(1, n + 1):
        for j in range(1, m + 1):
            
            # If the characters are equal
            if (X[i - 1] == Y[j - 1]):
                mat[i][j] = 1 + mat[i - 1][j - 1]
                
            # If not equal, then
            # just move to next
            # in subsequence string
            else:
                mat[i][j] = mat[i - 1][j]

    # Find maximum length of the
    # longest subsequence matching
    # substring of other string
    len1 = 0
    col = 0
    
    # Iterate through the last
    # row of matrix
    for i in range(0, m + 1):
        if (mat[n][i] > len1):
            len1 = mat[n][i]
            col = i

    # Store the required string
    res = ""
    i = n
    j = col
    
    # Backtrack from the cell
    while (len1 > 0):

        # If equal, then add the
        # character to res string
        if (X[i - 1] == Y[j - 1]):
            res = X[i - 1] + res
            i -= 1
            j -= 1
            len1 -= 1
        else:
            i -= 1

    # Return the required string
    return res

# Driver code
X = "ABCD"
Y = "ACDBDCD"

print(longestSubsequence(X, Y))

# This code is contributed by amreshkumar3
C#
// C# program for the above approach
using System;
using System.Collections.Generic;

class GFG{

// Function to find the longest
// subsequence that matches with
// the substring of other string
static string longestSubsequence(string X, string Y)
{
    int i, j;
    
    // Stores the lengths of strings
    // X and Y
    int n = X.Length;
    int m = Y.Length;

    // Create a matrix
    int [,]mat = new int[n + 1, m + 1];

    // Initialize the matrix
    for(i = 0; i < n + 1; i++) 
    {
        for(j = 0; j < m + 1; j++) 
        {
            if (i == 0 || j == 0)
                mat[i,j] = 0;
        }
    }

    // Fill all the remaining rows
    for(i = 1; i < n + 1; i++) 
    {
        for(j = 1; j < m + 1; j++)
        {
            
            // If the characters are equal
            if (X[i - 1] == Y[j - 1])
            {
                mat[i, j] = 1 + mat[i - 1, j - 1];
            }

            // If not equal, then
            // just move to next
            // in subsequence string
            else 
            {
                mat[i, j] = mat[i - 1, j];
            }
        }
    }

    // Find maximum length of the
    // longest subsequence matching
    // substring of other string
    int len = 0, col = 0;

    // Iterate through the last
    // row of matrix
    for(i = 0; i < m + 1; i++) 
    {
        if (mat[n,i] > len)
        {
            len = mat[n,i];
            col = i;
        }
    }

    // Store the required string
    string res = "";
    i = n;
    j = col;

    // Backtrack from the cell
    while (len > 0)
    {
        
        // If equal, then add the
        // character to res string
        if (X[i - 1] == Y[j - 1]) 
        {
            res = X[i - 1] + res;
            i--;
            j--;
            len--;
        }
        else
        {
            i--;
        }
    }

    // Return the required string
    return res;
}

// Driver Code
public static void Main()
{
    string X = "ABCD";
    string Y = "ACDBDCD";
    
    Console.Write(longestSubsequence(X, Y));
}
}

// This code is contributed by bgangwar59
JavaScript
<script>

// Javascript program for the above approach

// Function to find the longest
// subsequence that matches with
// the substring of other string
function longestSubsequence(X,Y)
{
        // Stores the lengths of strings
        // X and Y
        let n = X.length;
        let m = Y.length;
 
        // Create a matrix
        let mat = new Array(n + 1);
 
        // Initialize the matrix
        for (let i = 0; i < n + 1; i++) {
            mat[i]=new Array(m+1);
            for (let j = 0; j < m + 1; j++) {
                if (i == 0 || j == 0)
                    mat[i][j] = 0;
            }
        }
 
        // Fill all the remaining rows
        for (let i = 1;
             i < n + 1; i++) {
 
            for (let j = 1;
                 j < m + 1; j++) {
 
                // If the characters are equal
                if (X[i-1]
                    == Y[j-1]) {
                    mat[i][j] = 1
                                + mat[i - 1][j - 1];
                }
 
                // If not equal, then
                // just move to next
                // in subsequence string
                else {
                    mat[i][j] = mat[i - 1][j];
                }
            }
        }
 
        // Find maximum length of the
        // longest subsequence matching
        // substring of other string
        let len = 0, col = 0;
 
        // Iterate through the last
        // row of matrix
        for (let i = 0; i < m + 1; i++) {
 
            if (mat[n][i] > len) {
                len = mat[n][i];
                col = i;
            }
        }
 
        // Store the required string
        let res = "";
        let i = n;
        let j = col;
 
        // Backtrack from the cell
        while (len > 0) {
 
            // If equal, then add the
            // character to res string
            if (X[i-1]
                == Y[j-1]) {
 
                res = X[i-1] + res;
                i--;
                j--;
                len--;
            }
            else {
                i--;
            }
        }
 
        // Return the required string
        return res;
}

// Driver Code
let X = "ABCD";
let Y = "ACDBDCD";
document.write(longestSubsequence(X, Y));


// This code is contributed by unknown2108
</script>

Output: 
ACD

 

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


Next Article

Similar Reads