advanced9 min read·Updated October 5, 2026

Edit distance (Levenshtein) Explained: Tracing 'horse' to 'ros'

Master Levenshtein edit distance with a step-by-step trace of 'horse' to 'ros'. Build a 2D DP mental model, handle edge cases, and solve variations.

By Learnisim AI·Published October 5, 2026
LEARNING ARCSetup → Model in the example → Full trace → Twist → Edge cases → Apply
PREREQUISITES
  • basic 2D arrays
  • recursion and memoization
  • string indexing
Edit Distance (Levenshtein): Transforming "horse" → "ros" Dynamic Programming Matrix & Minimum Single-Character Operations The Spelling Dilemma exact equality: horse == ros Result: Distance = ∞ (No match) Binary check gives zero nuance. We need partial edit paths! 3 Core Operations • Delete: Cost 1 (Up ↓) • Insert: Cost 1 (Left →) • Substitute: 0 if match, 1 if diff dp[i][j] = min(delete, insert, subst) DP Grid: word1="horse" (rows) vs word2="ros" (cols) ε r o s ε 0 1 2 3 h 1 1 2 3 o 2 2 1 2 r 3 2 2 2 s 4 3 3 2 e 5 4 3 3 Target Edit Distance = 3 operations Path: 'h' deleted, 's'/'e' cleaned/matched The 3 Minimal Edits 1. Delete 'h' horse → orse (cost: 1) 2. Substitute 'e' → 's' orss → orss (cost: 2) 3. Delete 's' orss → ros (cost: 3) Optimal spelling correction achieved! Why DP Scales Subproblem Overlapping Instead of exponential brute-force, storing prefix sub-costs allows O(m × n) time complexity. Applications • Spell Checkers (Did you mean?) • DNA Sequence Alignment • Plagiarism Detection
Edit distance horse → ros overview diagram
Why

Why exact string matching fails when correcting typos

Phase 1: The spelling correction dilemma

Imagine you are building a search engine or spell checker, and a user types horse instead of the intended query ros. If you rely on exact string equality like word1 == word2, your system treats horse and ros as completely unrelated strings with a distance of infinity. Binary equality gives you zero nuance: two words are either identical or entirely different. But in real-world applications, we need to know how different they are, and what minimal set of single-character edits bridges the gap.
To quantify this difference, we turn to the locked working example of transforming word1 = horse into word2 = ros. Without a systematic distance metric, you cannot determine whether horse is closer to ros, house, or moose. We need a principled way to measure the minimum number of character operations required to turn one string into another.

Why simple heuristics fall short

You might be tempted to use simple length differences or shared character counts to measure similarity. However, string horse has length 5 and ros has length 3, a difference of 2, yet simply trimming characters ignores the required replacements and ordering shifts. Counting shared letters also fails because position and sequence matter immensely in human language. We need an algorithmic approach that accounts for insertions, deletions, and substitutions directly on the character stream.
Edit Distance (Levenshtein): Why Exact Matching Fails Transforming "horse" $\rightarrow$ "ros" requires quantified character edits, not binary equality. Naive Approach: word1 == word2 "horse" ≠ "ros" Result: Distance = ∞ (Completely Unrelated) Binary equality offers zero nuance for real-world typos & search queries. Levenshtein Solution: Minimal Single-Char Edits Start: h o r s e (len 5) Delete 'h' Step 1: o r s e (len 4) Substitute 'r'→'r' (match) Step 2: o r s (len 3) Delete 'e' Final: r o s (Target) Levenshtein Distance = 3 Operations (2 Deletions + 1 Match/Retain sequence) Why Simple Heuristics Fail × Length Difference Alone horse (5) vs ros (3) $\rightarrow$ diff is 2, but misses required steps. × Shared Letter Counting Ignores character position, order, and sequential alignment. Conclusion: Need sequential edit-distance matrices.
Why exact string matching fails when correcting typos diagram
Model

Modeling Edit Distance As A 2D Grid Of Subproblems

Phase 2: The Grid State-Space Model

When transforming horse into ros, we are not just making a single all-or-nothing guess; we are making a sequence of localized choices. To capture this systematically, we model the transformation as a two-dimensional grid of subproblems. Imagine a table where the rows correspond to the prefixes of word1 (h, ho, hor, hors, horse) plus an empty string, and the columns correspond to the prefixes of word2 (r, ro, s) plus an empty string.
Each cell at row and column in our matrix represents the exact edit distance required to convert the prefix of length from horse into the prefix of length from ros. By breaking the giant string-matching problem down into these tiny prefix comparisons, we turn a chaotic search space into a structured path-finding problem.
To move from one cell to the next, our model relies on three fundamental character-level operations:
- Deletion: Remove a character from horse, moving vertically down the grid.
- Insertion: Add a character to match ros, moving horizontally across the grid.
•Substitution: Swap a mismatched character, moving diagonally across the grid.
Instead of guessing the optimal sequence of these three operations upfront, our model calculates the cost of all three at every single step and greedily records the minimum. The top-left corner of the grid starts with zero cost for two empty strings, and our ultimate goal is to find the value resting in the bottom-right corner, which corresponds to the full word horse transformed into ros.
Levenshtein Edit Distance: horse → ros 2D Grid Subproblem Modeling & Optimal Path ε r o s ε h o r s e 0 1 2 3 1 1 2 3 2 2 1 2 3 2 2 2 4 3 3 2 5 4 3 3 Three Grid Transition Operations ↓ Deletion (Cost +1) Move down cell: drop char from word1 → Insertion (Cost +1) Move right cell: add char to match word2 ↘ Substitution / Match Diagonal move (+1 if mismatch, +0 if match) Minimization Recurrence (Dynamic Programming) dp[i][j] = min( dp[i-1][j] + 1, dp[i][j-1] + 1, dp[i-1][j-1] + cost ) Greedily evaluates all 3 paths at every subproblem cell in O(m × n) time. Result: Minimum Edit Distance = 3 Transforming "horse" → "ros": 1. r → r (match) 2. ho → o (delete h) 3. se → s (delete e, s)
Modeling Edit Distance As A 2D Grid Of Subproblems diagram
Worked example

Tracing the Edit Distance Matrix for horse and ros

Phase 3: Walking the Matrix

To see how dynamic programming solves our target transformation, let us execute the algorithm by hand for word1 = "horse" (rows, length 5) and word2 = "ros" (cols, length 3). We construct a grid of size (including empty string states at index 0).

Given

- word1 = horse (rows , where row 0 is empty string "")
- word2 = ros (cols , where col 0 is empty string "")

Steps

1. Initialize Base Cases: Fill row 0 with values (representing 0 to 3 insertions needed to form prefixes of ros from an empty ""). Fill column 0 with values (representing deletions needed to reduce prefixes of horse to "").
2. Row 1 (h vs "ros"): Compare h against r, o, s.
- At h vs r: characters differ ().
- Continuing across row 1 yields values: [1, 1, 2, 3].
3. Row 2 (o vs "ros"): Compare o. At column 2 (o vs o), characters match! So . The row becomes [2, 2, 1, 2].
4. Row 3 (r vs "ros"): Compare r. At column 1 (r vs r), characters match (). Row 3 fills out as [3, 2, 2, 2].
5. Row 4 (s vs "ros"): Compare s. At column 3 (s vs s), characters match (). Row 4 fills out as [4, 3, 3, 2].
6. Row 5 (e vs "ros"): Compare e against r, o, s. None match.
- For e vs s (bottom-right cell ): .

Result

The final bottom-right cell holds the value 3, which is our minimum edit distance.
Try this: Given the partially filled Levenshtein matrix for word1 = "horse" and word2 = "ros", explain what operation is represented when the algorithm takes the value from the diagonal-left cell () instead of computing .
Tracing Levenshtein Matrix: horse → ros ε r o s ε 0 1 2 3 h 1 1 2 3 o 2 2 1 2 r 3 2 2 2 s 4 3 3 2 e 5 4 3 3 Dynamic Programming Transition Rule: dp[i][j] = 1 + min(insert, delete, substitute) Key Rules Learned in this Step: If chars match (e.g., 'o' vs 'o'): Take diagonal-left value: dp[i][j] = dp[i-1][j-1] Bottom-right cell dp[5][3]: Holds final minimum edit distance = 3 Try this: What operation uses the diagonal-left cell? Result
Tracing the Edit Distance Matrix for horse and ros diagram
Practice

Applying Edit Distance to a New Sub-Problem Variation

Phase 4: Practice

Now that we have traced the full 5-by-3 matrix for transforming horse into ros and arrived at our expected cost of 3, let us test your understanding on a closely related variant using the same exact rules. Instead of the full words, suppose we want to compute the minimum edit distance to transform the prefix hor into the target prefix ro using the same three operations (insert, delete, replace at cost 1).
Recall the core transition rule from our previous steps:
$
Your task is to construct or mentally trace the smaller grid for transforming hor (rows, index 0 to 3 including empty string) into ro (columns, index 0 to 2 including empty string) and determine the final value at the bottom-right cell .
Try this: Given word1 = "hor" and word2 = "ro", construct the 2D DP matrix where rows represent prefixes of word1 and columns represent prefixes of word2. What is the final edit distance at the bottom-right cell dp[3][2]?
Apply

Applying Edit Distance to Spelling Correction Pipelines

Phase 5: Transfer

Now that you have traced the transformation of horse into ros with a cost of 3, you can apply this exact matrix recurrence to broader string-processing pipelines. In real-world spell checkers, you do not just check one target word against one dictionary entry; you compute edit distances across an entire vocabulary to find the minimum-cost matches.
Imagine you are building an autocomplete engine that receives the typo hors and needs to rank candidates from a dictionary containing horse, horsy, hose, and ros. Each candidate requires instantiating a grid of size and executing our recurrence relation.

Scaling the Algorithm

Because computing a full matrix for every word in a 100,000-word dictionary is computationally heavy, production systems apply optimizations like the Ukkonen's algorithm or length filtering. If the length difference between hors and a dictionary word exceeds your maximum allowed edit distance , you skip the grid calculation entirely.
python
def get_suggestions(typo, dictionary, max_distance=2):
    suggestions = []
    for word in dictionary:
        if abs(len(typo) - len(word)) <= max_distance:
            if compute_edit_distance(typo, word) <= max_distance:
                suggestions.append(word)
    return suggestions
By establishing our base case bounds and state transitions on small examples like horse and ros, we create a reliable primitive that scales up to fuzzy search, DNA sequence alignment, and natural language translation evaluation.
python
def rank_closest_word(target, vocabulary):
    # Apply your understanding of edit distance cost matrices
    # to return the word in vocabulary with the minimum distance to target.
    pass

FAQ

How does the edit distance algorithm transform 'horse' to 'ros'?
By finding the minimum cost of insertions, deletions, and substitutions. For 'horse' to 'ros', the minimum operations are 3: replace 'h' with 'r' (rorse), delete 'r' (rose), and delete 'e' (ros).
What is the time and space complexity of the edit distance algorithm?
The standard dynamic programming solution runs in O(m × n) time and O(m × n) space, where m and n are the lengths of the two strings. Space can be optimized to O(min(m, n)) by keeping track of only the previous row.
What are the three allowed operations in Levenshtein distance?
The operations are insertion of a character, deletion of a character, and substitution of one character for another. Each typically has a cost of 1.
When should I use Levenshtein distance over Hamming distance?
Use Levenshtein distance when strings can be of different lengths or require insertions and deletions. Hamming distance requires strings to be of equal length and only counts substitutions.

Keep learning