Longest common subsequence
A subsequence keeps the order of the characters but need not keep them adjacent. The table holds, for every pair of prefixes, the length of their longest common subsequence. If the two characters at the end of the prefixes are the same, that character can be used: the answer is one more than the answer for both prefixes shortened by one. If they differ, one of the two characters must be dropped, and the answer is the better of dropping either.
Its recurrence
L(i, j) = a[i] = b[j] ? 1 + L(i−1, j−1) : max( L(i−1, j), L(i, j−1) )
When it is the right choice
Anywhere two sequences have to be aligned rather than matched: diff tools, version control merges, spelling correction, comparing DNA. A file diff is exactly this algorithm with lines for characters — the lines it reports as unchanged are the longest common subsequence, and everything else is an insertion or a deletion.
How it works
- Make a table with one row per character of the first string plus a row for the empty prefix, and the same for the second string down the columns.
- Fill the first row and the first column with zeroes: nothing in common with nothing.
- For each pair of characters, compare them.
- If they match, take the cell diagonally up and to the left and add one.
- If they do not, take the larger of the cell above and the cell to the left.
- Walk back from the bottom-right, stepping diagonally wherever the characters matched, collecting those characters in reverse.
Worth noticing
- The two characters being compared are marked in the headers, not just in the cell. That is the whole reason the headers carry the strings rather than indices: the cell is about those two characters, and a table of numbers cannot say which.
- A match takes one arrow and a mismatch takes two, so the number of arrows on screen tells you which case you are in before you have read a single number.
- The length is in the bottom-right cell and the subsequence itself is only in the traceback. Two different subsequences can both be longest, and which one this page reports depends on which way it breaks a tie — it prefers going up.
Cost
- Best
- O(m · n)
- Average
- O(m · n)
- Worst
- O(m · n)
- Extra space
- O(m · n)
- Table
- two dimensions
- Accepts
- up to 16 characters in each string
The limits are pedagogical rather than technical: this tool keeps the whole table in every recorded step, so the shape of the table sets the size of the trace directly, and a run has to stay short enough to sit and watch. An input that would take more than three thousand steps on this algorithm is refused before a single step is generated, from a formula in the input sizes rather than by running it and finding out.
An unfilled cell is drawn differently from a cell holding a zero — no fill, a dashed outline, and no number at all — because early in a run that difference is most of the picture.