Edit Distance 編輯距離演算法 @LeetCode
阿新 • • 發佈:2019-02-02
思路:
又是一道典型DP!
我們將人生劃為詭異的階段
我們把這個世界表為豐富的狀態
package DP; import java.util.Arrays; /** * Edit Distance * * Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.) You have the following 3 operations permitted on a word: a) Insert a character b) Delete a character c) Replace a character */ public class EditDistance { static int[][] dist = null; public static void main(String[] args) { String word1 = "sdfsssjdfhsb"; String word2 = "cvdsfadfgkdfgj"; dist = new int[word1.length()+1][word2.length()+1]; for(int[] row : dist){ Arrays.fill(row, -1); } System.out.println(minDistance(word1, word2)); System.out.println(minDistance2(word1, word2)); } public static int min3(int a, int b, int c){ return Math.min(Math.min(a, b), c); } // DP bottom-up public static int minDistance(String word1, String word2) { int[][] distance = new int[word1.length()+1][word2.length()+1]; // 邊界情況:當其中一個string為空時,只要一直新增或刪除就可以 for(int i=0; i<=word1.length(); i++){ distance[i][0] = i; } for(int j=1; j<=word2.length(); j++){ distance[0][j] = j; } // 遞推,[i][j]處可以由左,上,左上3種情況而來 for(int i=1; i<=word1.length(); i++){ for(int j=1; j<=word2.length(); j++){ distance[i][j] = min3(distance[i-1][j]+1, // 從上演變 distance[i][j-1]+1, // 從左演變 distance[i-1][j-1]+(word1.charAt(i-1)==word2.charAt(j-1) ? 0 : 1)); // 從左上演變,考慮是否需要替換 } } return distance[word1.length()][word2.length()]; // 返回右下角 } // 遞迴,太慢 public static int minDistance2(String word1, String word2) { // return rec(word1, word1.length(), word2, word2.length()); return rec2(word1, word1.length(), word2, word2.length()); } public static int rec(String word1, int len1, String word2, int len2){ if(len1 == 0){ return len2; } if(len2 == 0){ return len1; } if(word1.charAt(len1-1) == word2.charAt(len2-1)){ return rec(word1, len1-1, word2, len2-1); }else{ return min3(rec(word1, len1-1, word2, len2-1) + 1, rec(word1, len1, word2, len2-1) + 1, rec(word1, len1-1, word2, len2) + 1); } } // 新增全域性陣列,儲存狀態,用空間換時間 DP top-down public static int rec2(String word1, int len1, String word2, int len2){ if(len1 == 0){ return len2; } if(len2 == 0){ return len1; } if(word1.charAt(len1-1) == word2.charAt(len2-1)){ if(dist[len1-1][len2-1] == -1){ dist[len1-1][len2-1] = rec2(word1, len1-1, word2, len2-1); } return dist[len1-1][len2-1]; }else{ if(dist[len1-1][len2-1] == -1){ dist[len1-1][len2-1] = rec2(word1, len1-1, word2, len2-1); } if(dist[len1][len2-1] == -1){ dist[len1][len2-1] = rec2(word1, len1, word2, len2-1); } if(dist[len1-1][len2] == -1){ dist[len1-1][len2] = rec2(word1, len1-1, word2, len2); } dist[len1][len2] = min3(dist[len1-1][len2-1]+1, dist[len1][len2-1]+1, dist[len1-1][len2]+1); return dist[len1][len2]; } } }
Ref:
這個視訊講的特別好!
public class Solution { public int minDistance(String word1, String word2) { int len1 = word1.length(); int len2 = word2.length(); if(len1 == 0) { return len2; } if(len2 == 0) { return len1; } int[][] ed = new int[len1+1][len2+1]; for(int i=0; i<=len1; i++) { ed[i][0] = i; } for(int j=0; j<=len2; j++) { ed[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)) { ed[i][j] = ed[i-1][j-1]; } else { ed[i][j] = Math.min(ed[i-1][j-1], Math.min(ed[i-1][j], ed[i][j-1])) + 1; } } } return ed[len1][len2]; } }