Skip to content
Related Articles

Related Articles

Improve Article

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

  • Difficulty Level : Hard
  • Last Updated : 06 Jul, 2021

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)

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.




My Personal Notes arrow_drop_up
Recommended Articles
Page :