LeetCode - Edit Distance

1 minute read

Problem description

description

Given two words word1 and word2, find the minimum number of operations required to convert word1 to word2.

You have the following 3 operations permitted on a word:

  1. Insert a character
  2. Delete a character
  3. Replace a character Example 1:
    1
    2
    3
    4
    5
    6
    
    Input: word1 = "horse", word2 = "ros"
    Output: 3
    Explanation: 
    horse -> rorse (replace 'h' with 'r')
    rorse -> rose (remove 'r')
    rose -> ros (remove 'e')
    

    Example 2:

    1
    2
    3
    4
    5
    6
    7
    8
    
    Input: word1 = "intention", word2 = "execution"
    Output: 5
    Explanation: 
    intention -> inention (remove 't')
    inention -> enention (replace 'i' with 'e')
    enention -> exention (replace 'n' with 'x')
    exention -> exection (replace 'n' with 'c')
    exection -> execution (insert 'u')
    

Analysis

The first thought is to use backtrack with wildcard. But the correct solution is to use DP.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Solution {
    public int minDistance(String word1, String word2) {
        int len1 = word1.length();
        int len2 = word2.length();
        
        if (len1 == 0 || len2 == 0){
            return len1+len2;
        }
        
        int[][] dp = new int[len1][len2];
        
        dp[0][0] = word1.charAt(0) == word2.charAt(0) ? 0:1;
        
        for (int i = 0; i < len1; i++){
            for (int j = 0; j < len2; j++){
                if (i == 0 && j == 0){
                    continue;
                }
                
                boolean equal = word1.charAt(i) == word2.charAt(j);
                
                if (i == 0){
                    dp[i][j] = equal ? j : dp [i][j-1] + 1; // should be j
                }
                else if (j == 0){
                    dp[i][j] = equal ? i : dp[i-1][j] + 1; // should be i
                }
                else {
                    dp[i][j] = equal ? dp[i-1][j-1] : Math.min(dp[i][j-1],Math.min(dp[i-1][j], dp[i-1][j-1])) + 1;
                }
            }
        }
        
        return dp[len1-1][len2-1];
    }
}

What to improve

  • ask for count but not details we should use dp

  • be careful about the base case.