Longest Common Subsequence (LCS) using Bottom-Up (Space-Optimization)

  • In the above tabulation approach we are using L[i-1][j] and L[i][j] etc, here the L[i-1] will refers to the matrix L’s previous row and L[i] refers to the current row.
  • We can do space optimization by using two vectors one is previous and another one is current.
  • When the inner for loop exits we are initializing previous equal to current.

Below is the implementation:

C++
// Dynamic Programming C++ implementation
// of LCS problem
#include <bits/stdc++.h>
using namespace std;

int longestCommonSubsequence(string& text1, string& text2)
{
    int n = text1.size();
    int m = text2.size();

    // initializing 2 vectors of size m
    vector<int> prev(m + 1, 0), cur(m + 1, 0);

    for (int idx2 = 0; idx2 < m + 1; idx2++)
        cur[idx2] = 0;

    for (int idx1 = 1; idx1 < n + 1; idx1++) {
        for (int idx2 = 1; idx2 < m + 1; idx2++) {
            // if matching
            if (text1[idx1 - 1] == text2[idx2 - 1])
                cur[idx2] = 1 + prev[idx2 - 1];

            // not matching
            else
                cur[idx2]
                    = 0 + max(cur[idx2 - 1], prev[idx2]);
        }
        prev = cur;
    }

    return cur[m];
}

int main()
{
    string S1 = "AGGTAB";
    string S2 = "GXTXAYB";

    // Function call
    cout << "Length of LCS is "
         << longestCommonSubsequence(S1, S2);

    return 0;
}
Java
// Dynamic Programming Java implementation of LCS problem

import java.util.Arrays;

public class GFG {

    public static int longestCommonSubsequence(String text1, String text2) {
        int n = text1.length();
        int m = text2.length();

        // Initializing 2 arrays of size m
        int[] prev = new int[m + 1];
        int[] cur = new int[m + 1];

        for (int idx1 = 1; idx1 < n + 1; idx1++) {
            for (int idx2 = 1; idx2 < m + 1; idx2++) {
                // If matching
                if (text1.charAt(idx1 - 1) == text2.charAt(idx2 - 1))
                    cur[idx2] = 1 + prev[idx2 - 1];
                // Not matching
                else
                    cur[idx2] = Math.max(cur[idx2 - 1], prev[idx2]);
            }
            prev = Arrays.copyOf(cur, m + 1);
        }

        return cur[m];
    }

    public static void main(String[] args) {
        String S1 = "AGGTAB";
        String S2 = "GXTXAYB";

        // Function call
        System.out.println("Length of LCS is " + longestCommonSubsequence(S1, S2));
    }
}
Python
def longestCommonSubsequence(text1, text2):
    n = len(text1)
    m = len(text2)

    # Initializing two lists of size m
    prev = [0] * (m + 1)
    cur = [0] * (m + 1)

    for idx1 in range(1, n + 1):
        for idx2 in range(1, m + 1):
            # If characters are matching
            if text1[idx1 - 1] == text2[idx2 - 1]:
                cur[idx2] = 1 + prev[idx2 - 1]
            else:
                # If characters are not matching
                cur[idx2] = max(cur[idx2 - 1], prev[idx2])

        prev = cur.copy()

    return cur[m]

if __name__ == '__main__':
    S1 = "AGGTAB"
    S2 = "GXTXAYB"

    # Function call
    print("Length of LCS is", longestCommonSubsequence(S1, S2))
# This code is contributed by Rishabh Mathur
C#
using System;

class Program
{
    static int LongestCommonSubsequence(string text1, string text2)
    {
        int n = text1.Length;
        int m = text2.Length;
        // initializing 2 arrays of size m
        int[] prev = new int[m + 1];
        int[] cur = new int[m + 1];
        for (int idx2 = 0; idx2 < m + 1; idx2++)
            cur[idx2] = 0;
        for (int idx1 = 1; idx1 < n + 1; idx1++)
        {
            for (int idx2 = 1; idx2 < m + 1; idx2++)
            {
                // if matching
                if (text1[idx1 - 1] == text2[idx2 - 1])
                    cur[idx2] = 1 + prev[idx2 - 1];
                // not matching
                else
                    cur[idx2] = 0 + Math.Max(cur[idx2 - 1], prev[idx2]);
            }
            prev = cur;
        }
        return cur[m];
    }
    static void Main()
    {
        string S1 = "AGGTAB";
        string S2 = "GXTXAYB";
        // Function call
        Console.WriteLine("Length of LCS is " + LongestCommonSubsequence(S1, S2));
    }
}
Javascript
function longestCommonSubsequence(text1, text2) {
    const n = text1.length;
    const m = text2.length;

    // Initializing two arrays of size m
    let prev = new Array(m + 1).fill(0);
    let cur = new Array(m + 1).fill(0);

    for (let idx2 = 0; idx2 < m + 1; idx2++) {
        cur[idx2] = 0;
    }

    for (let idx1 = 1; idx1 < n + 1; idx1++) {
        for (let idx2 = 1; idx2 < m + 1; idx2++) {
            // If characters match
            if (text1[idx1 - 1] === text2[idx2 - 1]) {
                cur[idx2] = 1 + prev[idx2 - 1];
            }
            // If characters don't match
            else {
                cur[idx2] = Math.max(cur[idx2 - 1], prev[idx2]);
            }
        }
        // Update the 'prev' array
        prev = [...cur];
    }

    return cur[m];
}

// Main function
function main() {
    const S1 = "AGGTAB";
    const S2 = "GXTXAYB";

    // Function call
    console.log("Length of LCS is " + longestCommonSubsequence(S1, S2));
}

// Call the main function
main();

Output
Length of LCS is 4

Time Complexity: O(m * n), which remains the same.
Auxiliary Space: O(m) because the algorithm uses two arrays of size m.



Longest Common Subsequence (LCS)

Given two strings, S1 and S2, the task is to find the length of the Longest Common Subsequence, i.e. longest subsequence present in both of the strings. 

A longest common subsequence (LCS) is defined as the longest subsequence which is common in all given input sequences.

Longest Common Subsequence


Examples:

Input: S1 = “ABC”, S2 = “ACD”
Output: 2
Explanation: The longest subsequence which is present in both strings is “AC”.

Input: S1 = “AGGTAB”, S2 = “GXTXAYB”
Output: 4
Explanation: The longest common subsequence is “GTAB”.

Input: S1 = “ABC”, S2 = “CBA”
Output: 1
Explanation: There are three common subsequences of length 1, “A”, “B” and “C” and no common subsequence.of length more than 1.

Input: S1 = “XYZW”, S2 = “XYWZ”
Output: 3
Explanation: There are two common subsequences of length 3 “XYZ”, and”XYW”, and no common subsequence. of length more than 3.

Similar Reads

Longest Common Subsequence (LCS) using Recursion:

Generate all the possible subsequences and find the longest among them that is present in both strings using recursion....

Longest Common Subsequence (LCS) using Memoization:

If we notice carefully, we can observe that the above recursive solution holds the following two properties:...

Longest Common Subsequence (LCS) using Bottom-Up (Tabulation):

We can use the following steps to implement the dynamic programming approach for LCS....

Longest Common Subsequence (LCS) using Bottom-Up (Space-Optimization):

In the above tabulation approach we are using L[i-1][j] and L[i][j] etc, here the L[i-1] will refers to the matrix L’s previous row and L[i] refers to the current row.We can do space optimization by using two vectors one is previous and another one is current. When the inner for loop exits we are initializing previous equal to current....

Contact Us