When a coding interview asks you to turn one word into another with the fewest changes, you’re looking at the edit distance pattern. It’s a dynamic‑programming (DP) classic that shows up in product‑design questions, text‑processing tasks, and even bio‑informatics. The core idea is simple: build a table where each cell tells you the cheapest way to align prefixes of the two strings.
Spotting the Edit Distance Pattern
| Signal in the prompt | What it means |
|---|---|
| "minimum number of operations" | Classic Levenshtein distance (insert, delete, replace). |
| "convert string A to string B" | Same as above; look for allowed operations. |
| "cost of each operation" | Weighted edit distance – you’ll need to store the cost in the DP transition. |
| "make two strings equal" or "make them anagrams" | May reduce to a simpler variant (e.g., only deletions). |
| "transform one DNA sequence into another" | Usually the same DP, but alphabet size can be large. |
If you see any of these, pause and consider a DP over the two strings’ lengths.
The Classic DP Derivation
Let s (length m) and t (length n) be the two strings. Define dp[i][j] as the minimum edits to turn s[:i] into t[:j]. The recurrence is:
if i == 0: dp[0][j] = j # j insertions
if j == 0: dp[i][0] = i # i deletions
otherwise:
dp[i][j] = min(
dp[i-1][j] + 1, # delete s[i-1]
dp[i][j-1] + 1, # insert t[j-1]
dp[i-1][j-1] + cost) # replace (cost 0 if same)
cost is 0 when s[i-1] == t[j-1], otherwise 1 (or a custom weight). The answer lives in dp[m][n].
Space Optimization
Only the previous row is needed to compute the current row, so you can shrink space to O(min(m,n)) by iterating over the shorter string as the inner dimension.
Worked Example in Python
def edit_distance(s: str, t: str) -> int:
# Ensure the inner loop is the shorter string
if len(s) < len(t):
s, t = t, s
prev = list(range(len(t) + 1)) # dp[0][*]
for i, sc in enumerate(s, 1):
cur = [i] + [0] * len(t)
for j, tc in enumerate(t, 1):
cost = 0 if sc == tc else 1
cur[j] = min(
prev[j] + 1, # delete
cur[j-1] + 1, # insert
prev[j-1] + cost # replace / match
)
prev = cur
return prev[-1]
print(edit_distance('kitten', 'sitting')) # → 3
The function runs in O(m·n) time and O(min(m,n)) space. It handles the three basic operations; you can extend it by passing a custom cost matrix.
Common Pitfalls
- Off‑by‑one indexing – Remember
dpincludes the empty‑prefix row/column. - Wrong base cases –
dp[0][j] = j(j insertions) anddp[i][0] = i(i deletions) are essential. - Forgetting to reset the current row – Each iteration must start with
cur[0] = i. - Assuming characters are unique – The algorithm works for any alphabet; don’t try to compress the strings unless the problem explicitly asks.
- Mixing operation costs – If the prompt gives different costs for insert/delete/replace, adjust the
+1terms accordingly.
Five Representative Practice Problems
1. Basic Levenshtein Distance
Prompt: "Given two lowercase strings, return the minimum number of insert, delete, or replace operations required to make them identical." Hint: Use the DP table described above. No extra constraints.
2. Weighted Edit Distance
Prompt: "Insert costs 1, delete costs 1, replace costs 2. Compute the cheapest transformation.
Hint: Replace the +1 in the recurrence with the appropriate weight. Keep the same DP shape.
3. Edit Distance with Only Insert/Delete (No Replace)
Prompt: "You may only insert or delete characters. What is the minimum number of operations to make the strings equal?"
Hint: This reduces to the length of the longest common subsequence (LCS). Compute LCS length and derive edits as len(s) + len(t) - 2*LCS.
4. Minimum Operations to Make Two Strings Anagrams
Prompt: "Given two strings consisting of lowercase letters, find the minimum deletions needed so that the remaining characters form anagrams of each other." Hint: Count frequencies of each letter. The answer is the sum of absolute differences across the alphabet.
5. Edit Distance with a Maximum Allowed Cost
Prompt: "Return true if the edit distance between two strings is ≤ k, otherwise false. k ≤ 5.
Hint: Use the classic DP but prune rows/columns where the cost already exceeds k. This yields an O(k·min(m,n)) solution.
How to Practice This
- Implement the core DP from scratch without copying code. Write the table, fill base cases, and verify with a few hand‑tested strings.
- Add a twist each time—custom costs, limited operations, or a bound on
k. This forces you to adapt the recurrence. - Explain the solution aloud as if you were in an interview. Tools like Call Assistant can capture your spoken explanation, keep the conversation on track, and let you rehearse follow‑up questions while staying grounded in your own experience.
FAQ
When should I consider edit distance vs. a simpler string‑comparison trick? If the problem mentions "minimum operations" or allows character‑level changes, DP is the safe bet. Simpler tricks (like counting mismatches) work only when the allowed operations are very restricted.
Can I use recursion instead of an explicit table? A memoized recursive solution works but has the same
O(m·n)time and usually higher constant overhead. In interviews, the iterative table is clearer.What if the strings are millions of characters long? Space‑optimized DP (
O(min(m,n))) is still linear in the shorter string. For truly massive inputs, you may need banded DP or heuristic approximations, but those are rarely asked.How do I handle Unicode or multi‑byte characters? Treat each code point as a character; Python’s strings already work that way. Just be aware of potential surrogate pairs in languages that expose raw bytes.
Frequently asked questions
When should I consider edit distance vs. a simpler string-comparison trick?
If the problem mentions "minimum operations" or allows character-level changes, DP is the safe bet. Simpler tricks (like counting mismatches) work only when the allowed operations are very restricted.
Can I use recursion instead of a explicit table?
A memoized recursive solution works but has the same O(m·n) time and usually higher constant overhead. In interviews, the iterative table is clearer.
What if the strings are millions of characters long?
Space‑optimized DP (O(min(m,n))) is still linear in the shorter string. For truly massive inputs you may need banded DP or heuristics, but those rarely appear in interviews.
How do I handle Unicode or multi-byte characters?
Treat each code point as a character; Python strings already behave that way. Just be aware of surrogate pairs in languages that expose raw bytes.
#coding pattern#edit distance#dynamic programming#interview prep#python