Longest Common Subsequence (LCS)
Finds the length (and optionally the sequence) of the longest subsequence present in both strings in the same relative order, using a 2D DP table.
Syntax
lcs(a, b) Parameters
| Name | Type | Required | Description |
|---|---|---|---|
a | string | Yes | First string. |
b | string | Yes | Second string. |
Returns
{ length: number, sequence: string } — Length of the LCS and one such subsequence string.
Examples
function lcs(a, b) {
const m = a.length, n = b.length;
const dp = Array.from({length: m + 1}, () => new Array(n + 1).fill(0));
for (let i = 1; i <= m; i++)
for (let j = 1; j <= n; j++)
if (a[i-1] === b[j-1]) dp[i][j] = dp[i-1][j-1] + 1;
else dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
// Backtrack to find the sequence
let i = m, j = n;
const seq = [];
while (i > 0 && j > 0) {
if (a[i-1] === b[j-1]) { seq.push(a[i-1]); i--; j--; }
else if (dp[i-1][j] > dp[i][j-1]) i--;
else j--;
}
return { length: dp[m][n], sequence: seq.reverse().join('') };
}
console.log(lcs('AGGTAB', 'GXTXAYB'));
Output
{ length: 4, sequence: 'GTAB' }
// LCS of two arrays (for diff tools)
function lcsArray(a, b) {
const m = a.length, n = b.length;
const dp = Array.from({length:m+1},()=>new Array(n+1).fill(0));
for(let i=1;i<=m;i++) for(let j=1;j<=n;j++)
dp[i][j] = a[i-1]===b[j-1] ? dp[i-1][j-1]+1 : Math.max(dp[i-1][j],dp[i][j-1]);
let i=m,j=n; const seq=[];
while(i>0&&j>0){ if(a[i-1]===b[j-1]){seq.push(a[i-1]);i--;j--;} else dp[i-1][j]>dp[i][j-1]?i--:j--; }
return seq.reverse();
}
console.log(lcsArray([1,3,4,5,6,7,8],[1,4,5,6,7,8,9]));
Output
[ 1, 4, 5, 6, 7, 8 ]
Notes
| Case | Time | Space |
|---------|-------|-------|
| Best | O(mn) | O(mn) |
| Average | O(mn) | O(mn) |
| Worst | O(mn) | O(mn) |
The DP table has m·n entries, each computed in O(1). Space can be
reduced to O(min(m,n)) using only two rows if only the length (not
the sequence) is needed. LCS is closely related to edit distance
(fewer operations needed when LCS is longer) and diff tools (Unix
`diff` uses LCS). For very long strings (m,n > 10k), consider
Myers' diff algorithm which runs in O(n·d) where d is the edit distance.