Skip to content
BytePatterns

Longest Common Subsequence

Dynamic Programming: lesson 6 of 20

Match the two ends, or drop a character from one side.

Lesson 6 of 20 · 6 min

Longest Common Subsequence

Step 1 of 16

One row per prefix of night, one column per prefix of eight. Each cell is the answer for those two prefixes.

The Idea

Compare two sequences from the end inward. If the last characters match, the answer is the answer for both shorter prefixes plus one. If they differ, drop the last character of one string or the other and keep whichever gives more. A grid indexed by prefix lengths stores every one of those sub-answers exactly once.

Real-World Example

A contract review tool diffing two drafts. It finds the longest run of clauses that appear, in order, in both versions, then flags everything outside that alignment as inserted or deleted. The run does not have to be unbroken, so an added paragraph in the middle costs nothing.

The Code

def lcs(a, b):
    grid = [[0] * (len(b) + 1) for _ in range(len(a) + 1)]
    for i in range(1, len(a) + 1):
        for j in range(1, len(b) + 1):
            if a[i - 1] == b[j - 1]:
                grid[i][j] = grid[i - 1][j - 1] + 1        # matched: take the diagonal
            else:
                grid[i][j] = max(grid[i - 1][j], grid[i][j - 1])
    return grid[len(a)][len(b)]

print(lcs("ABCBDAB", "BDCABA"))   # 4
print(lcs("night", "eight"))      # 4

Python

Your turn

Fill in the blank.

def lcs(a, b):
  g = [[0] * (len(b) + 1) for _ in range(len(a) + 1)]
  for i in range(1, len(a) + 1):
      for j in range(1, len(b) + 1):
          if a[i - 1] == b[j - 1]:
              g[i][j] = ___ + 1
          else:
              g[i][j] = max(g[i - 1][j], g[i][j - 1])
  return g[len(a)][len(b)]

print(lcs("common", "moon"))   # should print 3

Mini quiz

1 / 3

When the two current characters match, the cell takes:

New lessons land every few weeks

Leave an address and we will tell you when the next one is up. That is the only reason we will use it.

One address, stored so we can email you. Nothing else, ever.