Edit distance recursive algorithm -- Skiena
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
The recursive edit-distance algorithm described in Skiena's treatment is the direct formulation of the Levenshtein distance recurrence. It is elegant because it mirrors the definition of the problem, but the plain recursive version is exponentially slow unless you add memoization or convert it to dynamic programming.
The Recursive Recurrence
Edit distance asks for the minimum number of insertions, deletions, and substitutions needed to turn one string into another.
Let dist(i, j) be the edit distance between the first i characters of one string and the first j characters of the other. Then:
- if
i == 0, the answer isj - if
j == 0, the answer isi - if the last characters match, recurse on
dist(i - 1, j - 1) - otherwise take
1 + min(insert, delete, substitute)
That recurrence is the core of the algorithm.
A Plain Recursive Implementation
Output:
This is correct, but it repeats the same subproblems many times.
Why the Plain Recursive Version Is Slow
Consider dist(6, 7) for "kitten" and "sitting". The recursive calls branch into smaller suffix comparisons, but many of those comparisons overlap. The same pair of prefix lengths can be reached through different paths, so the recursion tree grows quickly.
That is why the naive recursive solution has exponential behavior in the worst case.
Memoization Fixes the Main Problem
The natural improvement is to cache results by (i, j):
This keeps the recursive structure that Skiena emphasizes while reducing the number of unique subproblems to (m + 1) * (n + 1).
Relationship to Dynamic Programming
Memoized recursion and bottom-up dynamic programming solve the same subproblems. The difference is evaluation order:
- top-down recursion solves only the states it reaches
- bottom-up DP fills the table systematically
For edit distance, the bottom-up table is often easier to debug and usually avoids Python recursion-depth limits. But the recursive form is excellent for understanding the recurrence itself.
Common Pitfalls
- Presenting the plain recursive version as efficient for large strings. It is not.
- Forgetting the base cases when one prefix length becomes zero.
- Confusing insert, delete, and substitute transitions.
- Using recursion in Python for very large inputs without memoization.
- Thinking memoization changes the algorithmic idea. It keeps the same recurrence and just avoids repeated work.
Summary
- Skiena's recursive edit-distance algorithm follows the Levenshtein recurrence directly.
- The base cases handle empty prefixes, and mismatches branch into insert, delete, and substitute.
- The plain recursive form is conceptually clean but exponentially slow.
- Memoization turns it into an efficient top-down dynamic programming solution.
- For practical use, choose memoization or bottom-up DP rather than raw recursion alone.
Related reading
- Edmonds-Karp Algorithm for a graph which has nodes with flow capacities
- Effect of randomness on search results
- Effective queries in machine learning
- Effective unique on unordered elements
- Effectively sorting when your data is distributed across different microservices
- Efficiency of crossover in genetic algorithms
- Efficient Algorithm for Bit Reversal from MSB-LSB to LSB-MSB in C
- Efficient algorithm for converting a character set into a nfa/dfa

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.