class Solution {
public int minDistance(String word1, String word2) {
int dp[][]=new int[word1.length()+1][word2.length()+1];//dp[i][j]代表word1[i-1]为结尾与word2[j-1]为结尾的最少操作数
//这里创建dp数组额外多一个行列原因:
//1.如果不加1,边界值为dp[word1.length()-1][word2.length()-1],代表的是word1[word1.length()-2]和word[word2.length()-2]为结尾的最少操作数,遍历不到字符串结尾
//如果加1,边界值为dp[word1.length()][word2.length()],代表的是word1[word1.length()-1]和word2[word2.length()-1]为结尾的最少操作数,此时遍历到字符串结尾了
//2.如果不加1,初始化后对于特殊字符串(word1=a,word2=a word1=a,word2=b word1=ab,word2=ba)没有足够的距离去计算dp[i-1][j],dp[i][j-1]dp[i-1][j-1]
//初始化dp
//对于dp[i][0]代表word2为空串时(j=0)word1变成word2的操作数,此时word1有多长就减去word1的长度就行所以直接存放i
for(int i=0;i<=word1.length();i++)
{
dp[i][0]=i;
}
//对于dp[0][j]代表word1为空串时(i=0)word2变成word1的操作数,此时word2有多长就减去word2的长度就行所以直接存放j
for(int j=0;j<=word2.length();j++)
{
dp[0][j]=j;
}
//由于初始化所以第一行第一列都有初始值,直接从第二行第二列开始遍历即可
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
{
//此处只列举了减去word1当前字符,减去word2当前字符,替换word1或word2操作,三个操作。
//因为删除word1和增加word2操作实质一样,增加word1和删除word2操作实质一样,替换word1或是Word2实质都是为了使当前位置的字符相等也是一样的
int del1=dp[i-1][j]+1;//减去word1的当前字符,因为dp第[i]指的是当前以word1[i-1]为结尾的字符位置,减去当前字符往前移一位就是word[i-2]的位置,为dp的[i-1]行
int del2=dp[i][j-1]+1;//减去word2的当前字符,因为dp第[j]指的是当前以word2[j-1]为结尾的字符位置,减去当前字符往前移一位就是word[j-2]的位置,为dp的[j-1]列
int re1=dp[i-1][j-1]+1;//替换word1或word2的当前字符使之相等,已知如果当前位置相等dp[i][j]=dp[i-1][j-1],当前新增了替换操作才使之相等所以要在原有相等操作情况下加一的操作数
dp[i][j]=Math.min(del1,Math.min(del2,re1));//最少操作数所,以当前dp[i][j]存放三者操作的最小值
}
}
}
return dp[word1.length()][word2.length()];//此处返回word1[word1.length()-1][word2.length()-1]的最少操作数为最后结果,此时也遍历到了两个字符串结尾
}
}