题目描述
给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
- 插入一个字符
- 删除一个字符
- 替换一个字符
输入:word1 = "horse", word2 = "ros"
输出:3
解释:
horse -> rorse (将 'h' 替换为 'r')
rorse -> rose (删除 'r')
rose -> ros (删除 'e')
求解思路(看评论区学到的,呜呜呜太难了)
动态规划的思想:
设二维数组dp[i][j]表示word1[0,...,i]转换为word2[0,...,j]需要的最少操作数
则dp[i][j]由以下三种途径得到:
- 已知dp[i-1][j-1],意味着word1[0,...,i-1]已经转换为了word2[0,...,j-1],则需要考虑word1的第i个字符和word2的第j个字符。若相等,不需要操作,则dp[i][j]=dp[i-1][j-1];若不等,需要替换一次,则dp[i][j]=dp[i-1][j-1]+1。
- 已知dp[i][j-1],意味着word1[0,...,i]已经转换为了word2[0,...,j-1],则需要增加一个字符,dp[i][j]=dp[i][j-1]+1
- 已知dp[i-1][j],意味着word1[0,...,i-1]已经转换为了word2[0,...,j],则需要删除一个字符,dp[i][j]=dp[i-1][j]+1
取三种情况的最小值,便可得到状态转移方程,如下:
代码
执行用时:6 ms, 在所有 Java 提交中击败了87.35%的用户
内存消耗:38.7 MB, 在所有 Java 提交中击败了14.99%的用户
class Solution {
public int minDistance(String word1, String word2) {
int len1 = word1.length();
int len2 = word2.length();
int[][] dp = new int[len1+1][len2+1];
dp[0][0] = 0; //初始化
for(int i=1;i<=len1;i++){ //初始化
dp[i][0] = i;
}
for(int j=1;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] = Math.min(dp[i-1][j-1],Math.min(dp[i][j-1]+1,dp[i-1][j]+1));
}else{
dp[i][j] = Math.min(dp[i-1][j-1]+1,Math.min(dp[i][j-1]+1,dp[i-1][j]+1));
}
}
}
return dp[len1][len2];
}
}