Wednesday, February 4, 2015

Edit distance LeetCode

1. word1.charAt(i) == word2.charAt(j) dp[i][j] = dp[i-1][j-1];
2. word1.charAt(i) != word2.charAt(j) dp[i][j]  = 1+ min {dp[i][j-1], dp[i-1][j], dp[i-1][j-1]}

public int minDistance(String word1, String word2) {
        // IMPORTANT: Please reset any member data you declared, as
        // the same Solution instance will be reused for each test case.
        int len1 = word1.length();
        int len2 = word2.length();
int[][] dp = new int[len1 + 1][len2 + 1];

   for (int i=0; i<=len1; i++) {
       dp[i][0] = i;
   }
   for (int j=0; j<=len2; j++) {
       dp[0][j] = j;
   }
   
   for (int i=1; i<=len1; i++) {
       for (int j=1; j<=len2; j++) {
           if (word1.charAt(i-1) == word2.charAt(j-1)) {
               dp[i][j] = dp[i-1][j-1];
           } else {
               int temp = Math.min(dp[i-1][j], dp[i][j-1]);
               dp[i][j] = 1 + Math.min(dp[i-1][j-1], temp);
           }
       }
   }
   return dp[len1][len2];
    }

Here is the solution from the Wiki.
http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance

 private static int minimum(int a, int b, int c) {                            
        return Math.min(Math.min(a, b), c);                                      
    }                                                                            
 
    public static int computeLevenshteinDistance(String str1,String str2) {      
        int[][] distance = new int[str1.length() + 1][str2.length() + 1];        
 
        for (int i = 0; i <= str1.length(); i++)                                 
            distance[i][0] = i;                                                  
        for (int j = 1; j <= str2.length(); j++)                                 
            distance[0][j] = j;                                                  
 
        for (int i = 1; i <= str1.length(); i++)                                 
            for (int j = 1; j <= str2.length(); j++)                             
                distance[i][j] = minimum(                                        
                        distance[i - 1][j] + 1,                                  
                        distance[i][j - 1] + 1,                                  
                        distance[i - 1][j - 1] + ((str1.charAt(i - 1) == str2.charAt(j - 1)) ? 0 : 1));
 
        return distance[str1.length()][str2.length()];                           
    }                                                                            

Given a better solution with Space Complexity O(n) and Time Complexity O(m);
public int LevenshteinDistance (String s0, String s1) {                          
    int len0 = s0.length() + 1;                                                     
    int len1 = s1.length() + 1;                                                     
 
    // the array of distances                                                       
    int[] cost = new int[len0];                                                     
    int[] newcost = new int[len0];                                                  
 
    // initial cost of skipping prefix in String s0                                 
    for (int i = 0; i < len0; i++) cost[i] = i;                                     
 
    // dynamically computing the array of distances                                  
 
    // transformation cost for each letter in s1                                    
    for (int j = 1; j < len1; j++) {                                                
        // initial cost of skipping prefix in String s1                             
        newcost[0] = j;                                                             
 
        // transformation cost for each letter in s0                                
        for(int i = 1; i < len0; i++) {                                             
            // matching current letters in both strings                             
            int match = (s0.charAt(i - 1) == s1.charAt(j - 1)) ? 0 : 1;             
 
            // computing cost for each transformation                               
            int cost_replace = cost[i - 1] + match;                                 
            int cost_insert  = cost[i] + 1;                                         
            int cost_delete  = newcost[i - 1] + 1;                                  
 
            // keep minimum cost                                                    
            newcost[i] = Math.min(Math.min(cost_insert, cost_delete), cost_replace);
        }                                                                           
 
        // swap cost/newcost arrays                                                 
        int[] swap = cost; cost = newcost; newcost = swap;                          
    }                                                                               
 
    // the distance is the cost for transforming all letters in both strings        
    return cost[len0 - 1];                                                          
}

No comments:

Post a Comment