题目描述
给定两个单词word1和word2,请计算将word1转换为word2至少需要多少步操作。
你可以对一个单词执行以下3种操作:
a)在单词中插入一个字符
b)删除单词中的一个字符
c)替换单词中的一个字符
你可以对一个单词执行以下3种操作:
a)在单词中插入一个字符
b)删除单词中的一个字符
c)替换单词中的一个字符
解析:
D[i][j-1] 为 A 的前 i 个字符和 B 的前 j - 1 个字符编辑距离的子问题。即对于 B 的第 j 个字符,我们在 A 的末尾添加了一个相同的字符,那么 D[i][j] 最小可以为 D[i][j-1] + 1;
D[i-1][j] 为 A 的前 i - 1 个字符和 B 的前 j 个字符编辑距离的子问题。即对于 A 的第 i 个字符,我们在 B 的末尾添加了一个相同的字符,那么 D[i][j] 最小可以为 D[i-1][j] + 1;
D[i-1][j-1] 为 A 前 i - 1 个字符和 B 的前 j - 1 个字符编辑距离的子问题。即对于 B 的第 j 个字符,我们修改 A 的第 i 个字符使它们相同,那么 D[i][j] 最小可以为 D[i-1][j-1] + 1。特别地,如果 A 的第 i 个字符和 B 的第 j 个字符原本就相同,那么我们实际上不需要进行修改操作。在这种情况下,D[i][j] 最小可以为 D[i-1][j-1]。
那么我们可以写出如下的状态转移方程:
1 import java.util.*; 2 3 4 public class Solution { 5 /** 6 * 7 * @param word1 string字符串 8 * @param word2 string字符串 9 * @return int整型 10 */ 11 public int minDistance (String word1, String word2) { 12 if(word1.equals(word2)) return 0; 13 int m=word1.length(); 14 int n=word2.length(); 15 if (n * m == 0) 16 return n + m; 17 int[][] dp=new int[m+1][n+1]; 18 for(int i=1;i<m;i++){ 19 dp[i][0]=i; 20 } 21 for(int i=1;i<n;i++){ 22 dp[0][i]=i; 23 } 24 for(int i=1;i<=m;i++){ 25 for(int j=1;j<=n;j++){ 26 int left=dp[i-1][j]+1; 27 int right=dp[i][j-1]+1; 28 int left_down=dp[i-1][j-1]; 29 if(word1.charAt(i-1)!=word2.charAt(j-1)){ 30 left_down+=1; 31 } 32 dp[i][j]=Math.min(Math.min(left,right),left_down); 33 } 34 } 35 return dp[m][n]; 36 } 37 }