JavaScript Program for Longest Common Subsequence
Last Updated :
03 Jun, 2024
The longest common subsequence (LCS) is defined as the longest subsequence which is common in all given input sequences. In this article, we are given two strings, String1 and String2, the task is to find the longest common subsequence in both of the strings. A subsequence of a string can be achieved by deleting any number of elements from the string.
Example:
Input: 'ABCD' , 'AEBECED'
Output: 'ABCD'
Explanation: As 'ABCD' is common in both of the string and it is the longest string.
Brute force Method
In this approach, the idea is to generate all the sub-sequences and then to find the longest common subsequence in them. The problem with this approach is having very high time complexity. We need (2 to power n) time complexity to generate all the subsequences of a single string.
Example: This example shows the use of the above-explained approach.
JavaScript
function subseqProd(str) {
const subsequences = [];
function backtrack(subsequence, index) {
if (index === str.length) {
subsequences.push(subsequence);
return;
}
backtrack(subsequence + str[index], index + 1);
backtrack(subsequence, index + 1);
}
backtrack('', 0);
return subsequences;
}
function findLCS(str1, str2) {
const subseq1 = subseqProd(str1);
const subSeq2 = subseqProd(str2);
let lcs = '';
for (const sub1 of subseq1) {
for (const sub2 of subSeq2) {
if (sub1 === sub2 && sub1.length > lcs.length) {
lcs = sub1;
}
}
}
return lcs;
}
const str1 = "ABCDF";
const str2 = "ACDF";
const lcsSeq = findLCS(str1, str2);
console.log("Longest Common Subsequence: " + lcsSeq);
OutputLongest Common Subsequence: ACDF
Time Complexity: O(2^n*2^m), where n and m are length of string.
Space Complexity: O(2^n)
Using DP array
- In this approach, We will use this DP array to get the longest common subsequence in both strings.
- By keeping track of a pointer , We will start to fill the string `str` from the end .
- We will start by positioning from the rightmost place in the DP array, which is denoted by `(i, j)` with `i = n` & `j = m`. At every cell, we will check whether `S1[i-1]` matches `S2[j-1]` or not. If they matches , it shows that this character can be included to the longest common substring.
- If we found the previous case we will add the character to end of the `str`. Then, we will move to diagonally top-left cell (↖) by decrementing both of `i` & `j`.
- However, it is obvious that if the characters do not match, it tells that the character is not the part of the longest common subsequence.
- In this case, we look whether value in the cell to the left (←) or above (↑) is greater. And move to the cell which has the greater value.
- We will keep on repeating this process until `i` and `j` are greater than 0. and if they become less than zero, we will exit the loop
Example: This example shows the use of the above-explained approach.
JavaScript
function findLCS(s1, s2) {
const n = s1.length;
const m = s2.length;
const dp =
new Array(n + 1).fill(null).map(() =>
new Array(m + 1).fill(0));
for (let i = 0; i <= n; i++) {
dp[i][0] = 0;
}
for (let i = 0; i <= m; i++) {
dp[0][i] = 0;
}
for (let ind1 = 1; ind1 <= n; ind1++) {
for (let ind2 = 1; ind2 <= m; ind2++) {
if (s1[ind1 - 1] === s2[ind2 - 1]) {
dp[ind1][ind2] = 1 + dp[ind1 - 1][ind2 - 1];
} else {
dp[ind1][ind2] =
Math.max(dp[ind1 - 1][ind2],
dp[ind1][ind2 - 1]);
}
}
}
const len = dp[n][m];
let i = n;
let j = m;
let index = len - 1;
let str = "";
for (let k = 0; k < len; k++) {
str += "$"; // Dummy string
}
while (i > 0 && j > 0) {
if (s1[i - 1] === s2[j - 1]) {
str =
str.slice(0, index) + s1[i - 1] +
str.slice(index + 1);
index--;
i--;
j--;
} else if (s1[i - 1] > s2[j - 1]) {
i--;
} else {
j--;
}
}
return str;
}
const s1 = "abcdek";
const s2 = "bdgek";
console.log(
"The Longest Common Subsequence is " + findLCS(s1, s2));
OutputThe Longest Common Subsequence is bdek
Space Complexity: O(N*M)
Time Complexity: O(N*M)
Using Memoization (Top-Down Dynamic Programming)
In this approach, we'll use memoization to efficiently solve the problem by storing the results of previously solved subproblems.
- Create a memoization table (an array of arrays) to store the length of the LCS for different prefixes of the two strings.
- Define a recursive function to compute the LCS of two substrings, considering all possible cases.
- Use memoization to avoid redundant calculations by storing the results of subproblems in the memoization table.
- The base cases for the recursion are when either of the strings becomes empty. In such cases, the length of the LCS is 0.
- If the characters at the current positions in both strings match, we include this character in the LCS and recursively compute the LCS for the remaining substrings.
- If the characters don't match, we consider two possibilities: either excluding the current character from the first string or excluding it from the second string, and we take the maximum of the lengths of the LCS obtained from these two possibilities.
- Finally, return the length of the LCS, which is stored in the memoization table.
Here's the implementation in JavaScript:
JavaScript
function findLCS(s1, s2) {
const memo = new Array(s1.length + 1).fill(null).map(() => new Array(s2.length + 1).fill(-1));
function lcsHelper(i, j) {
if (i === 0 || j === 0) return 0;
if (memo[i][j] !== -1) return memo[i][j];
if (s1[i - 1] === s2[j - 1])
memo[i][j] = 1 + lcsHelper(i - 1, j - 1);
else
memo[i][j] = Math.max(lcsHelper(i - 1, j), lcsHelper(i, j - 1));
return memo[i][j];
}
lcsHelper(s1.length, s2.length);
let i = s1.length, j = s2.length;
let lcs = "";
while (i > 0 && j > 0) {
if (s1[i - 1] === s2[j - 1]) {
lcs = s1[i - 1] + lcs;
i--;
j--;
} else if (memo[i - 1][j] > memo[i][j - 1])
i--;
else
j--;
}
return lcs;
}
// Test Case
const s1 = "ABCDEK";
const s2 = "BDEGK";
console.log("Longest Common Subsequence: " + findLCS(s1, s2)); // Output: ABF
OutputLongest Common Subsequence: BDEK
Similar Reads
JavaScript Program for Printing Shortest Common Supersequence A Shortest Common Supersequence (SCS) is the shortest or smallest string that contains two given strings as a subsequence. It is a minimal combination of characters that includes all elements of both input strings. In this article, we will see different approaches for printing the shortest common su
8 min read
JavaScript Program to Find Longest Common Substring Between Two Strings In this article, we will see how to find the longest common substring between two strings in JavaScript. A substring is a contiguous sequence of characters within a string. It can be obtained by extracting part of the string starting from any position. We are going to write a JavaScript function tha
4 min read
Javascript Program to Find the Longest Bitonic Subsequence | DP-15 Given an array arr[0 ... n-1] containing n positive integers, a subsequence of arr[] is called Bitonic if it is first increasing, then decreasing. Write a function that takes an array as argument and returns the length of the longest bitonic subsequence. A sequence, sorted in increasing order is con
3 min read
Longest Palindromic Subsequence in C++ In this article, we will learn how to find the Longest Palindromic Subsequence (LPS) of a sequence using C++ programming language. LPS is the longest subsequence of a given sequence that reads the same backward as forward.Example:Input:Sequence: "BBABCBCAB"Output:Length of LPS is 7Explanation: The L
7 min read
Longest Increasing Subsequence in C In this article, we will learn how to find the Longest Increasing Subsequence (LIS) of a given sequence using C programming language. LIS is the longest subsequence of a sequence such that all elements of the subsequence are sorted in increasing order.Example:Input:Sequence: [10, 22, 9, 33, 21, 50,
9 min read
Javascript Program for Longest subsequence of a number having same left and right rotation Given a numeric string S, the task is to find the maximum length of a subsequence having its left rotation equal to its right rotation. Examples: Input: S = "100210601" Output: 4 Explanation: The subsequence "0000" satisfies the necessary condition. The subsequence "1010" generates the string "0101"
4 min read
Javascript Program To Find Longest Common Prefix Using Word By Word Matching Given a set of strings, find the longest common prefix. Examples:Input : {âgeeksforgeeksâ, âgeeksâ, âgeekâ, âgeezerâ}Output : "gee"Input : {"apple", "ape", "april"}Output : "ap"We start with an example. Suppose there are two strings- âgeeksforgeeksâ and âgeeksâ. What is the longest common prefix in
3 min read
Longest Palindromic Subsequence in Python Longest Palindromic Subsequence (LPS) problem is about finding the longest subsequence of the given sequence which is a palindrome. In Python, the task of maximizing the number of words in a sentence can be solved by the methods of dynamic programming. The algorithm for finding the Longest Palindrom
4 min read
Optimizing Arithmetic Progressions in Subsequences Given a string S, a string T is considered good if following 2 conditions hold: T is a subsequence of SThe indices of the subsequence T in S forms an arithmetic progression For example, if S = "aaabb" then T = "aab" is good because T is subsequence of S at indices 1,3,5 which is an arithmetic progre
8 min read
How to Find the Longest Common Prefix of Two Strings in Java? In this article, we will find the longest common prefix of two Strings in Java. Examples: Input: String 1= geeksforgeeks, String 2 = geezerOutput: âgeeâ Input: String 1= flower, String 2 = flightOutput: âflâ Methods to Find the Longest common Prefix of two Strings in JavaBelow are the methods by whi
4 min read