Edit Distance Problem Levenshtein in DSA Javascript - Time & Space Complexity
We want to understand how the time needed to find the edit distance between two words grows as the words get longer.
The question is: how does the number of steps change when the input words become bigger?
Analyze the time complexity of the following code snippet.
function levenshteinDistance(str1, str2) {
const dp = Array(str1.length + 1).fill(null).map(() => Array(str2.length + 1).fill(0));
for (let i = 0; i <= str1.length; i++) {
for (let j = 0; j <= str2.length; j++) {
if (i === 0) dp[i][j] = j;
else if (j === 0) dp[i][j] = i;
else if (str1[i - 1] === str2[j - 1]) dp[i][j] = dp[i - 1][j - 1];
else dp[i][j] = 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
}
}
return dp[str1.length][str2.length];
}
This code calculates the minimum number of edits needed to change one word into another using a table to store results.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Nested loops filling a 2D table of size (length of str1 + 1) by (length of str2 + 1).
- How many times: The inner loop runs for each character of str2 for every character of str1, so total steps are roughly (str1.length + 1) * (str2.length + 1).
As the words get longer, the number of steps grows by multiplying their lengths.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 100 steps |
| 100 | About 10,000 steps |
| 1000 | About 1,000,000 steps |
Pattern observation: Doubling the length of both words roughly quadruples the work needed.
Time Complexity: O(m * n)
This means the time needed grows proportionally to the product of the lengths of the two words.
[X] Wrong: "The algorithm runs in linear time because it just compares characters one by one."
[OK] Correct: The algorithm compares all pairs of characters in two words, so it must check a grid of size m by n, not just a single line.
Understanding this time complexity helps you explain how dynamic programming solves problems efficiently by avoiding repeated work.
"What if we used recursion without storing results? How would the time complexity change?"
Practice
Solution
Step 1: Understand the definition of Levenshtein distance
It measures how many single-character edits (insertions, deletions, or substitutions) are needed to convert one string into another.Step 2: Compare with other options
Options B, C, and D do not describe edit distance but other unrelated string properties.Final Answer:
The minimum number of single-character edits needed to change one string into the other -> Option CQuick Check:
Levenshtein distance = minimum edits [OK]
- Confusing edit distance with matching characters count
- Thinking it measures length difference only
- Assuming it counts only substitutions
s1 and s2?Solution
Step 1: Identify required parameters for Levenshtein function
The function needs exactly two strings to compare, so it should accept two parameters.Step 2: Check options for correct parameter count
function levenshtein(s1, s2) { /* code */ } has two parameters (s1, s2), which is correct. Options A, B, and C have incorrect parameter counts.Final Answer:
function levenshtein(s1, s2) { /* code */ } -> Option AQuick Check:
Two strings needed as input [OK]
- Using wrong number of parameters
- Omitting parameters entirely
- Adding unnecessary extra parameters
function min(a, b, c) {
return Math.min(a, b, c);
}
function levenshtein(s1, s2) {
const len1 = s1.length;
const len2 = s2.length;
const dp = Array(len1 + 1).fill(null).map(() => Array(len2 + 1).fill(0));
for (let i = 0; i <= len1; i++) dp[i][0] = i;
for (let j = 0; j <= len2; j++) dp[0][j] = j;
for (let i = 1; i <= len1; i++) {
for (let j = 1; j <= len2; j++) {
if (s1[i - 1] === s2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + 1);
}
}
}
return dp[len1][len2];
}
console.log(levenshtein('kitten', 'sitting'));Solution
Step 1: Understand the Levenshtein distance calculation for 'kitten' and 'sitting'
Transform 'kitten' to 'sitting' requires 3 substitutions and 1 insertion: k->s, i->i (same), t->t (same), t->t (same), e->i, n->n (same), plus insert 'g'. Total edits = 3.Step 2: Trace the code logic
The code correctly implements the dynamic programming approach to calculate the minimum edits, returning 3.Final Answer:
3 -> Option AQuick Check:
Levenshtein('kitten', 'sitting') = 3 [OK]
- Counting only substitutions
- Ignoring insertions or deletions
- Misindexing string characters
function levenshtein(s1, s2) {
const len1 = s1.length;
const len2 = s2.length;
const dp = Array(len1).fill(null).map(() => Array(len2).fill(0));
for (let i = 0; i <= len1; i++) dp[i][0] = i;
for (let j = 0; j <= len2; j++) dp[0][j] = j;
for (let i = 1; i <= len1; i++) {
for (let j = 1; j <= len2; j++) {
if (s1[i - 1] === s2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + 1);
}
}
}
return dp[len1][len2];
}Solution
Step 1: Analyze dp array initialization
The dp array is initialized with size len1 x len2, but the loops access indices up to len1 and len2, causing out-of-bounds errors.Step 2: Fix dp size to (len1+1) x (len2+1)
Allocating dp with one extra row and column prevents index errors and allows proper initialization of base cases.Final Answer:
Change dp array initialization to size (len1+1) x (len2+1) -> Option DQuick Check:
dp size must match loop bounds [OK]
- Not allocating dp with extra row/column
- Using wrong loop ranges causing errors
- Replacing min with max breaks logic
s1 = 'intention' and s2 = 'execution', what is the Levenshtein distance between them? Use the concept of minimum edits (insertions, deletions, substitutions) to find the answer.Solution
Step 1: Analyze differences between 'intention' and 'execution'
Transform 'intention' to 'execution' involves substitutions and insertions: i->e, n->x, t->c, e->u, n->t, plus insert 'o'. Total edits count to 6.Step 2: Count minimum edits carefully
Counting substitutions and insertions needed gives 6 as the minimum number of edits.Final Answer:
6 -> Option BQuick Check:
Minimum edits between 'intention' and 'execution' = 6 [OK]
- Underestimating substitutions needed
- Ignoring insertions or deletions
- Confusing with string length difference
Ready to prove it?
Pass the test and this pattern moves unknown
