medium Edit Distance
Problem Statement
Given two strings word1 and word2, return the least number of edits needed to transform word1 to word2.
You can perform any one edit from below three in a single operation on Word:
Inserta characterDeletea characterReplacea character
Examples
-
Example 1:
- Input: word1 =
"cat", word2 ="cut" - Expected Output: 1
- Justification: Only one operation is needed, replacing 'a' with 'u' in "cat" to make it "cut".
- Input: word1 =
-
Example 2:
- Input: word1 =
"sun", word2 ="satur" - Expected Output: 3
- Justification: Three operations needed: 1) Insert 'a' after 's', 2) Insert 't' after 'a', and 3) Replace 'n' with 'r'.
- Input: word1 =
-
Example 3:
- Input: word1 =
"book", word2 ="back" - Expected Output: 2
- Justification: Two operations are required: 1) Replace 'o' with 'a', and 2) Replace the second 'o' with 'c'. This changes "book" to "back".
- Input: word1 =
Try it yourself
Try solving this question here:
✅ Solution Edit Distance
Problem Statement
Given two strings word1 and word2, return the least number of edits needed to transform word1 to word2.
You can perform any one edit from below three in a single operation on Word:
Inserta characterDeletea characterReplacea character
Examples
-
Example 1:
- Input: word1 =
"cat", word2 ="cut" - Expected Output: 1
- Justification: Only one operation is needed, replacing 'a' with 'u' in "cat" to make it "cut".
- Input: word1 =
-
Example 2:
- Input: word1 =
"sun", word2 ="satur" - Expected Output: 3
- Justification: Three operations needed: 1) Insert 'a' after 's', 2) Insert 't' after 'a', and 3) Replace 'n' with 'r'.
- Input: word1 =
-
Example 3:
- Input: word1 =
"book", word2 ="back" - Expected Output: 2
- Justification: Two operations are required: 1) Replace 'o' with 'a', and 2) Replace the second 'o' with 'c'. This changes "book" to "back".
- Input: word1 =
Solution
To solve this problem, we'll use dynamic programming due to its efficiency in solving problems that involve making a sequence of decisions. The core idea is to break down the problem into simpler, smaller subproblems and store their solutions to avoid redundant calculations. This approach works well here because the edit distance between two substrings can be built up from the edit distances of their prefixes, allowing for an efficient bottom-up calculation.
The effectiveness of this approach lies in its ability to consider all possible edit operations in a systematic way. By examining the relationships between the edits required for different substring lengths, we can construct a solution that covers all possible paths from the start string to the target string, ensuring that the minimum edit distance is found. This method not only guarantees accuracy but also significantly reduces computational overhead compared to naive recursive approaches.
Step-by-Step Algorithm
-
Initialization: Start by creating a 2D array,
dp, with dimensions[word1.length() + 1][word2.length() + 1]. This array will hold the minimum number of operations required to convert substrings ofword1to substrings ofword2. The+1accounts for the zero-length substrings of both words. -
Base Cases: Fill in the base cases in the
dparray.- Fill the first row,
dp[0][j], withj, representing the minimum number of insert operations needed to convert an empty string into the firstjcharacters ofword2. - Fill the first column,
dp[i][0], withi, representing the minimum number of delete operations needed to convert the firsticharacters ofword1into an empty string.
- Fill the first row,
-
Filling the DP Table: Iterate through each cell of the
dparray starting fromdp[1][1]todp[word1.length()][word2.length()]. For each celldp[i][j], compute the minimum of the following operations:- Deletion: Remove a character from
word1. This operation is represented bydp[i-1][j] + 1. - Insertion: Add a character to
word1to match a character inword2. This operation is represented bydp[i][j-1] + 1. - Replacement: If the current characters in
word1andword2don't match, replace the character inword1with the matching character fromword2. This operation is represented bydp[i-1][j-1] + 1. If the characters already match, simply carry over the value fromdp[i-1][j-1].
- Deletion: Remove a character from
-
Result: After filling the
dptable, the value indp[word1.length()][word2.length()]will be the minimum number of operations required to convertword1intoword2.
Algorithm Walkthrough
Let's walkthrough the Input: word1 = "sun", word2 = "saturday"
Initial DP Array
We initialize the DP array with dimensions [4][6] (since "sun" has 3 characters and "satur" has 5 characters, plus 1 for the base case of the empty string).
dp = [
[x, x, x, x, x, x],
[x, x, x, x, x, x],
[x, x, x, x, x, x],
[x, x, x, x, x, x]
]
Fill First Row and Column
- The first row is filled with
0to5, representing the operation count needed to convert an empty string to each prefix of "satur". - The first column is filled with
0to3, representing the operation count needed to convert each prefix of "sun" to an empty string.
After filling the first row and column:
dp = [
[0, 1, 2, 3, 4, 5],
[1, x, x, x, x, x],
[2, x, x, x, x, x],
[3, x, x, x, x, x]
]
i = 0 (Comparing "s" with each character of "satur")
- "s" with "s": They match, so we carry over the value from
dp[0][0], makingdp[1][1] = 0. - "s" with "a": They don't match, so we consider the minimum of the operations above, left, and diagonal-left plus one, making
dp[1][2] = 1. - "s" with "t": They don't match, continuing the logic, making
dp[1][3] = 2. - "s" with "u": They don't match, making
dp[1][4] = 3. - "s" with "r": They don't match, making
dp[1][5] = 4.
After comparisons:
dp = [
[0, 1, 2, 3, 4, 5],
[1, 0, 1, 2, 3, 4],
[2, x, x, x, x, x],
[3, x, x, x, x, x]
]
i = 1 (Comparing "u" with each character of "satur")
- "u" with "s": Doesn't match, so we take the minimum of operations above, left, and diagonal-left plus one, making
dp[2][1] = 1. - "u" with "a": Doesn't match, continue with the logic, making
dp[2][2] = 1. - "u" with "t": Doesn't match, making
dp[2][3] = 2. - "u" with "u": They match, so we carry over the value from
dp[1][3], makingdp[2][4] = 2. - "u" with "r": Doesn't match, making
dp[2][5] = 3.
After comparisons:
dp = [
[0, 1, 2, 3, 4, 5],
[1, 0, 1, 2, 3, 4],
[2, 1, 1, 2, 2, 3],
[3, x, x, x, x, x]
]
i = 2 (Comparing "n" with each character of "satur")
- "n" with "s": Doesn't match, so we take the minimum of operations above, left, and diagonal-left plus one, making
dp[3][1] = 2. - "n" with "a": Doesn't match, continue with the logic, making
dp[3][2] = 2. - "n" with "t": Doesn't match, making
dp[3][3] = 2. - "n" with "u": Doesn't match, making
dp[3][4] = 3. - "n" with "r": Doesn't match, making
dp[3][5] = 3.
After comparisons:
dp = [
[0, 1, 2, 3, 4, 5],
[1, 0, 1, 2, 3, 4],
[2, 1, 1, 2, 2, 3],
[3, 2, 2, 2, 3, 3]
]
Result
The minimum number of operations required to transform "sun" into "satur" is found in dp[3][5], which is 3.
Code
public class Solution {
public int minDistance(String word1, String word2) {
// Creating a DP table to store the minimum operations required
int[][] dp = new int[word1.length() + 1][word2.length() + 1];
// Initializing the first row and column of the DP table
for (int i = 0; i <= word1.length(); i++) {
dp[i][0] = i;
}
for (int j = 0; j <= word2.length(); j++) {
dp[0][j] = j;
}
// Filling the DP table
for (int i = 1; i <= word1.length(); i++) {
for (int j = 1; j <= word2.length(); j++) {
if (word1.charAt(i - 1) == word2.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]));
}
}
}
// Returning the value in the bottom-right corner of the DP table
return dp[word1.length()][word2.length()];
}
public static void main(String[] args) {
Solution solution = new Solution();
System.out.println(solution.minDistance("cat", "cut")); // Example 1
System.out.println(solution.minDistance("sun", "satur")); // Example 2
System.out.println(solution.minDistance("book", "back")); // Example 3
}
}
Complexity Analysis
- Time Complexity: The algorithm iterates through each character of both strings once to fill the DP table, resulting in a time complexity of
, where mandnare the lengths ofword1andword2, respectively. - Space Complexity: The space complexity is also
due to the DP table that stores the edit distances between all prefixes of the two strings.
🤖 Don't fully get this? Learn it with Claude
Stuck on Edit Distance? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Progressively stronger hints — you still solve it.
I'm working on the problem **Edit Distance** (DSA). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
See the technique, not just code.
Explain the optimal approach to **Edit Distance** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Catch bugs, edge cases, sub-optimality.
I'll paste my solution to **Edit Distance**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Lock in recognition with look-alikes.
Give me 2 problems that use the SAME underlying pattern as **Edit Distance**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.