Edit Distance Problem Levenshtein in DSA Java - 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 increase in length?
Analyze the time complexity of the following code snippet.
public int levenshtein(String s1, String s2) {
int m = s1.length();
int n = s2.length();
int[][] dp = new int[m + 1][n + 1];
for (int i = 0; i <= m; i++) dp[i][0] = i;
for (int j = 0; j <= n; j++) dp[0][j] = j;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (s1.charAt(i - 1) == s2.charAt(j - 1))
dp[i][j] = dp[i - 1][j - 1];
else
dp[i][j] = 1 + Math.min(dp[i - 1][j - 1], Math.min(dp[i - 1][j], dp[i][j - 1]));
}
}
return dp[m][n];
}
This code calculates the minimum number of edits (insert, delete, replace) to change one word into another using a table.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Nested loops filling a 2D table of size m by n.
- How many times: The inner loop runs n times for each of the m iterations of the outer loop, so about m x n times.
As the lengths of the two words grow, the number of steps grows roughly by multiplying their lengths.
| Input Size (m, n) | Approx. Operations |
|---|---|
| 10, 10 | 100 |
| 100, 100 | 10,000 |
| 1000, 1000 | 1,000,000 |
Pattern observation: Doubling the length of both words roughly quadruples the work because the table size grows with the product of lengths.
Time Complexity: O(m x 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 a table, not just one by one, so it takes time proportional to both word lengths multiplied.
Understanding this time complexity helps you explain how dynamic programming solves problems efficiently by breaking them into smaller parts.
"What if we used recursion without memoization? How would the time complexity change?"
Practice
Solution
Step 1: Understand the definition of Edit Distance
Edit Distance counts how many changes are needed to turn one string into another using insert, delete, or substitute operations.Step 2: Compare options with definition
Only The minimum number of insertions, deletions, or substitutions to convert one string into another correctly describes the minimum number of these operations needed.Final Answer:
The minimum number of insertions, deletions, or substitutions to convert one string into another -> Option AQuick Check:
Edit Distance = minimum edits [OK]
- Confusing edit distance with common substring length
- Thinking it measures only character matches
- Assuming it counts only insertions or deletions
s1 and s2?Solution
Step 1: Identify the return type for Levenshtein distance
The Levenshtein distance is a number representing the count of edits, so the return type should beint.Step 2: Check method signature correctness
public int levenshteinDistance(String s1, String s2) returnsintand takes twoStringparameters, which is correct. Other options return void, String, or boolean, which are incorrect for this purpose.Final Answer:
public int levenshteinDistance(String s1, String s2) -> Option DQuick Check:
Return type int for distance [OK]
- Using void return type and not returning a value
- Returning String instead of int
- Returning boolean which is not suitable
"kitten" and "sitting"?Solution
Step 1: Compare strings and count edits
Transform "kitten" to "sitting": substitute 'k'->'s', substitute 'e'->'i', insert 'g' at end. Total edits = 3.Step 2: Confirm minimal edits
No fewer than 3 edits can convert "kitten" to "sitting".Final Answer:
3 -> Option BQuick Check:
kitten -> sitting needs 3 edits [OK]
- Counting only substitutions and missing insertions
- Miscounting edits by skipping characters
- Assuming length difference equals distance
public int levenshteinDistance(String s1, String s2) {
int[][] dp = new int[s1.length()][s2.length()];
for (int i = 0; i <= s1.length(); i++) {
for (int j = 0; j <= s2.length(); j++) {
if (i == 0) dp[i][j] = j;
else if (j == 0) dp[i][j] = i;
else if (s1.charAt(i - 1) == s2.charAt(j - 1)) dp[i][j] = dp[i - 1][j - 1];
else dp[i][j] = 1 + Math.min(dp[i - 1][j - 1], Math.min(dp[i][j - 1], dp[i - 1][j]));
}
}
return dp[s1.length()][s2.length()];
}Solution
Step 1: Check dp array size
dp is declared as new int[s1.length()][s2.length()] but loops run up to s1.length() and s2.length() inclusive, causing index out of bounds.Step 2: Identify correct dp size
dp should be new int[s1.length()+1][s2.length()+1] to accommodate indices up to s1.length() and s2.length().Final Answer:
Array dp is declared with wrong size causing IndexOutOfBoundsException -> Option CQuick Check:
dp size must be length+1 [OK]
- Declaring dp with exact string lengths only
- Returning dp at wrong indices
- Starting loops incorrectly causing errors
"intention" and "execution"?Solution
Step 1: Align the strings and identify differences
Both strings have length 9. The minimal edit sequence includes substitutions and insertions/deletions. The Levenshtein distance is 6, as confirmed by standard DP computation.Step 2: Confirm no better alignment
Insertions/deletions and substitutions combined yield a minimum of 6 edits.Final Answer:
6 -> Option AQuick Check:
intention -> execution = 6 [OK]
- Counting 6 by proposing unnecessary insert/delete
- Underestimating by ignoring all mismatches (e.g., 4)
- Overestimating due to poor alignment
Ready to prove it?
Pass the test and this pattern moves unknown
