Introduction

Three classical DP problems act on sequences: the longest common subsequence (LCS) of two strings, the edit distance (Levenshtein distance) between two strings, and the longest increasing subsequence (LIS) of one sequence. Each fills a table whose state is a pair of prefixes (or a single prefix with an auxiliary structure), and each is a standard GATE dynamic-programming question.

This note states the recurrences, works a full LCS table with traceback, and records the O(n2)O(n^2) and O(nlg⁡n)O(n \lg n) routes to LIS.

Prerequisites

Core concepts

Subsequence versus substring

A subsequence preserves order but need not be contiguous. A substring (or subarray) is contiguous. LCS and LIS ask for subsequences. A string of length mm has 2m2^m subsequences (counting repeats), which is why brute force over subsequences is hopeless and DP is needed.

Longest common substring is different. Its state is "longest common suffix of X[1..i]X[1..i] and Y[1..j]Y[1..j]": s[i,j]=s[i−1,j−1]+1s[i,j] = s[i-1,j-1] + 1 if X[i]=Y[j]X[i] = Y[j], and s[i,j]=0s[i,j] = 0 otherwise. The answer is the maximum entry of the table, not the bottom-right entry. For ABCBDAB and BDCABA the longest common substring has length 2 (for example AB), while the LCS has length 4.

State for two strings

For strings X[1..m]X[1..m] and Y[1..n]Y[1..n], the natural state is "answer for the prefixes X[1..i]X[1..i] and Y[1..j]Y[1..j]" with 0≤i≤m0 \le i \le m and 0≤j≤n0 \le j \le n. That gives an (m+1)×(n+1)(m+1) \times (n+1) table. Base row and column correspond to an empty prefix.

Algorithms and pseudocode

Pseudocode uses 1-based arrays, <- for assignment and X[i] for the ii-th character of XX.

Longest common subsequence

c[i,j]={0if i=0 or j=0,c[i−1,j−1]+1if i,j>0 and X[i]=Y[j],max⁡(c[i−1,j], c[i,j−1])if i,j>0 and X[i]≠Y[j].c[i,j] = \begin{cases} 0 & \text{if } i = 0 \text{ or } j = 0, \\ c[i-1,j-1] + 1 & \text{if } i,j > 0 \text{ and } X[i] = Y[j], \\ \max\bigl(c[i-1,j],\, c[i,j-1]\bigr) & \text{if } i,j > 0 \text{ and } X[i] \ne Y[j]. \end{cases}
Text
LCS-LENGTH(X, Y)
 1  m <- X.length;  n <- Y.length
 2  let c[0..m, 0..n] be a new table
 3  for i <- 0 to m
 4      c[i, 0] <- 0
 5  for j <- 0 to n
 6      c[0, j] <- 0
 7  for i <- 1 to m
 8      for j <- 1 to n
 9          if X[i] = Y[j] then
10              c[i, j] <- c[i - 1, j - 1] + 1
11          else c[i, j] <- max(c[i - 1, j], c[i, j - 1])
12  return c[m, n]

Time / space. Θ(mn)\Theta(mn) time and space. Length alone needs only the previous row: O(min⁡(m,n))O(\min(m,n)) extra space. Reconstructing one LCS walks from c[m,n]c[m,n] toward c[0,0]c[0,0]: on a match, collect X[i]X[i] and step diagonally; reverse the collected characters before output; otherwise step to the neighbour of equal value.

Edit distance

Allowed operations: insert one character, delete one character, substitute one character (each cost 1). Let d[i,j]d[i,j] be the edit distance of X[1..i]X[1..i] and Y[1..j]Y[1..j].

d[i,j]={iif j=0,jif i=0,d[i−1,j−1]if X[i]=Y[j],1+min⁡(d[i−1,j], d[i,j−1], d[i−1,j−1])otherwise.d[i,j] = \begin{cases} i & \text{if } j = 0, \\ j & \text{if } i = 0, \\ d[i-1,j-1] & \text{if } X[i] = Y[j], \\ 1 + \min\bigl(d[i-1,j],\, d[i,j-1],\, d[i-1,j-1]\bigr) & \text{otherwise.} \end{cases}

(The three options are delete, insert and substitute.) Time Θ(mn)\Theta(mn). If substitute is forbidden, drop the diagonal option and force a delete-plus-insert of cost 2 when characters differ.

Link to LCS. With insertions and deletions only, the distance is exactly m+n−2 LCS(X,Y)m + n - 2\,\mathrm{LCS}(X,Y): keep a longest common subsequence, delete the other m−LCSm - \mathrm{LCS} characters of XX and insert the other n−LCSn - \mathrm{LCS} characters of YY.

Longest increasing subsequence

Related material. LIS is not named separately in the GATE syllabus; it is included because it is the standard one-sequence DP companion of LCS.

O(n2)O(n^2) DP. Let L[i]L[i] be the length of a longest increasing subsequence ending at index ii. Then L[i]=1+max⁡{L[j]:j<i, A[j]<A[i]}L[i] = 1 + \max\{ L[j] : j < i,\ A[j] < A[i] \}, or 11 if no such jj. Answer max⁡iL[i]\max_i L[i]. Time Θ(n2)\Theta(n^2).

O(nlg⁡n)O(n \lg n) patience method. Maintain an array tail[k] = smallest tail value of any increasing subsequence of length kk seen so far. For each A[i]A[i], binary-search the first tail entry ≥A[i]\ge A[i] and replace it (or append). The length of tail is the LIS length. Time O(nlg⁡n)O(n \lg n). Strict versus non-decreasing is controlled by using << versus ≤\le in the search.

LCS of AA with a sorted copy of AA (duplicates removed, for a strictly increasing LIS) also yields LIS in O(n2)O(n^2) and makes the connection to LCS explicit (CLRS Exercise 15.4-5).

Mathematical explanation

Correctness sketch for LCS

Any LCS of X[1..i]X[1..i] and Y[1..j]Y[1..j] either ends with the matched pair X[i]=Y[j]X[i] = Y[j] (and the rest is an LCS of the shorter prefixes) or omits X[i]X[i] or omits Y[j]Y[j]. Those three cases partition the possibilities and justify the recurrence (CLRS 3e, Section 15.4).

Why edit distance is DP

An optimal alignment of the two prefixes ends with a match/substitute of the last characters, a deletion of X[i]X[i], or an insertion of Y[j]Y[j]. Optimal substructure follows by the usual cut-and-paste argument; the table has O(mn)O(mn) overlapping states.

Worked examples

LCS of ABCBDAB and BDCABA

X=X = A B C B D A B (m=7m = 7), Y=Y = B D C A B A (n=6n = 6).

The length table c[i,j]c[i,j] (rows XX, columns YY):

ε\varepsilonBDCABA
ε\varepsilon0000000
A0000111
B0111122
C0112222
B0112233
D0122233
A0122334
B0122344

Length c[7,6]=4c[7,6] = 4. The backward traceback collects ABCB; reversing that buffer gives the LCS BCBA. Exactly three distinct strings are LCSs here: BCAB, BCBA and BDAB. A traceback that prefers "up" on ties and one that prefers "left" can return different strings; both are correct.

LCS length table with one traceback path
Figure 1. LCS length table for X=X = ABCBDAB and Y=Y = BDCABA: the bottom-right entry is 4, and one traceback (heavy arrows) collects ABCB backward; reversing it recovers the common subsequence BCBA.

Edit distance of KITTEN and SITTING

KITTEN→SITTEN(substitute K/S),SITTEN→SITTIN(substitute E/I),SITTIN→SITTING(insert G).\begin{align*} \text{KITTEN} &\to \text{SITTEN} && \text{(substitute K/S)}, \\ \text{SITTEN} &\to \text{SITTIN} && \text{(substitute E/I)}, \\ \text{SITTIN} &\to \text{SITTING} && \text{(insert G)}. \end{align*}

Distance 3. The DP table's bottom-right entry is 3. With insertions and deletions only, the distance becomes 6+7−2⋅4=56 + 7 - 2 \cdot 4 = 5, since LCS(KITTEN,SITTING)=4\mathrm{LCS}(\text{KITTEN}, \text{SITTING}) = 4 (ITTN).

A full edit-distance table: ABC to YABD

Rows are prefixes of X=X = ABC, columns are prefixes of Y=Y = YABD; the first row and column are the base cases d[0,j]=jd[0,j] = j and d[i,0]=id[i,0] = i.

ε\varepsilonYABD
ε\varepsilon01234
A11123
B22212
C33322

d[3,4]=2d[3,4] = 2: insert Y in front, keep A and B, substitute C by D. Cell d[1,2]=1d[1,2] = 1 comes from the match A = A on the diagonal: d[0,1]=1d[0,1] = 1.

LIS of 10, 22, 9, 33, 21, 50, 41, 60

O(n2)O(n^2): lengths ending at each index are 1,2,1,3,2,4,4,51,2,1,3,2,4,4,5. LIS length 5, for example 10,22,33,50,6010,22,33,50,60.

Patience method (replace the first tail entry ≥\ge the new value, else append):

Read102293321504160
tail after1010, 229, 229, 22, 339, 21, 339, 21, 33, 509, 21, 33, 419, 21, 33, 41, 60

The final size is 5, the LIS length. The final tail array is not itself an increasing subsequence of the input: 9, 21, 33, 41, 60 would need 33 to come after 21, but 33 appears earlier. Recovering an actual LIS needs predecessor pointers.

Alignment view of edit distance

Edit distance equals the minimum cost of an alignment of the two strings, where a column is a matched or substituted pair, a deletion (character of XX against a gap), or an insertion (gap against a character of YY). The DP recurrence evaluates the best last column of any alignment of the two prefixes. This view makes the three-way min⁡\min memorable: diagonal = substitute or match, up = delete, left = insert.

Important properties and observations

  • LCS length is symmetric: LCS(X,Y)=LCS(Y,X)\mathrm{LCS}(X,Y) = \mathrm{LCS}(Y,X). The specific subsequence recovered depends on traceback ties.
  • Empty-string base cases are zeros for LCS and index values for edit distance; mixing them is a common error.
  • The LPS length equals the LCS length of a string and its reverse: LPS(X)=LCS(X,XR)\mathrm{LPS}(X) = \mathrm{LCS}(X, X^R). To recover a palindrome, use an LPS recurrence or a reconstruction guaranteed to return a palindrome; an arbitrary LCS need not be palindromic. For BBABCBCAB it is 7 (BABCBAB). CLRS Problem 15-2 treats this problem.
  • The unmemoized LCS recursion is exponential in the worst case (when no characters match, each call spawns two calls); the table has only (m+1)(n+1)(m+1)(n+1) distinct states.
  • LIS O(nlg⁡n)O(n \lg n) returns the length easily; recovering the subsequence needs predecessor pointers.

Common misconceptions.

  • "LCS is contiguous." That would be the longest common substring.
  • "Edit distance always allows substitution at cost 1." Some questions set substitute cost to 2 (delete + insert) or forbid it; read the statement.
  • "LIS requires strictly increasing." Confirm strict versus non-decreasing in the question.

GATE examination perspective

  • COMPLETE THE TABLE. A question may give a partially filled LCS or edit-distance table; compute the next cell from the recurrence.
  • TRACEBACK. State whether ties prefer up or left; both are correct for length.
  • COMPLEXITY. Θ(mn)\Theta(mn) for LCS and edit distance; Θ(n2)\Theta(n^2) or O(nlg⁡n)O(n \lg n) for LIS.
  • VARIANT COSTS. Insertion, deletion and substitution may have unequal costs; the recurrence becomes a weighted min⁡\min.
  • COUNT THE LCSs. "How many distinct LCSs?" means distinct strings, not distinct traceback paths; enumerate carefully (three for ABCBDAB and BDCABA).
  • SUBSTRING OR SUBSEQUENCE. Longest common substring resets to 0 on a mismatch and takes the table maximum.
  • INSERT/DELETE ONLY. Distance =m+n−2 LCS= m + n - 2\,\mathrm{LCS}.

Summary

Sources

  1. T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein, Introduction to Algorithms, 3rd ed., MIT Press, 2009: Chapter 15, Section 15.4 (longest common subsequence); Exercise 15.4-5 (LIS via LCS) and Exercise 15.4-6 (O(n lg n) LIS); Problem 15-2 (longest palindrome subsequence).

Next steps