◀ THE GRIND — 2-D DYNAMIC PROGRAMMING

Longest Common Subsequence

The drill: Two strings — find the length of the longest sequence of characters that appears in both, in the same relative order, without needing the characters to sit next to each other.

THE BRIEFING — THE FULL DRILL, IN MY OWN WORDS

Two strings arrive, and the task is to find the length of the longest sequence of characters that shows up in both — in the same relative order in each — without those characters needing to sit next to each other in either string.

Characters can be skipped freely on either side to line the subsequence up; the only rule is that the relative order of the chosen characters can't be rearranged. An empty subsequence is always trivially shared, so the answer is never negative.

Only the length of that longest shared subsequence is needed, not the subsequence's actual characters.

EX 01
text1 = "z" · text2 = "z"
1
SINGLE MATCHING CHARACTER
EX 02
text1 = "z" · text2 = "q"
0
NO CHARACTER IN COMMON AT ALL
EX 03
text1 = "track" · text2 = "tak"
3
THE HINTS — TAKE ONLY WHAT YOU NEED
HINT 1 THE NUDGE

Compare the last character of each string. If they match, that pair belongs in some longest common subsequence — what question is left once you strip it off?

HINT 2 THE STRUCTURE

If the last characters differ, the answer for the two full strings is the better of two smaller answers: drop the last character of the first string, or drop the last character of the second.

HINT 3 ONE STEP FROM THE ANSWER

DP table dp[i][j] = LCS length using the first i characters of text1 and first j of text2. Match → dp[i-1][j-1] + 1. Mismatch → max(dp[i-1][j], dp[i][j-1]).

COACH'S BOARD — THE PATTERN, STEP BY STEP
MATCH OR CARRYPATTERN · GRID DP, MATCH OR SKIPtext1 = "stride" · text2 = "tides"
0
0
0
0
0
0
STEP 1

Row 0 and column 0 both start at zero — matching an empty prefix against anything shares nothing.

STEP 1 / 7 · ← → WORK TOO
THE SPLITS — TWO PACES, TWO LANGUAGES
grind/longest-common-subsequence.pyRACE PACE
LANG ▸
PACE ▸
class Solution:
    def longestCommonSubsequence(self, text1: str, text2: str) -> int:
        m, n = len(text1), len(text2)
        dp = [[0] * (n + 1) for _ in range(m + 1)]
        for i in range(1, m + 1):
            for j in range(1, n + 1):
                if text1[i - 1] == text2[j - 1]:
                    dp[i][j] = dp[i - 1][j - 1] + 1
                else:
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
        return dp[m][n]
TIME O(M·N)SPACE O(M·N)PYTHON · RACE PACE · 11 LN

✓ CHIP-TIMED — ALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED