算法--动态规划
给两个单词word1和word2
求将word1变成word2的最少操作
操作:insert:插入一个字符
delete:删除一个字符
replace:替换一个字符
第一次是在leetcode动态规划(leetcode72)看到的,后面做某公司笔试真题的时候又见到了,自己想的太简单了,记录一下解法。
动态规划三步:
1.定义数组含义
首先定义word1长度是i,word2长度j,dp[i][j]代表转换的最少操作数
我们要做的是逐一比较word1[1~i]和word2[1~j]
相同 就同时移步 dp[i][j]==dp[i-1][j-1]
不同,有三种操作
替换:直接在word1【i】中替换一个与word2【j】对应位置相同的字符 ,两边需要都移位,操作数+1
dp[i][j]==dp[i-1][j-1] + 1
删除:把字符word[i]删除,用i-1位再继续比较,则 dp[i][j]==dp[i-1][j] + 1
插入:在word1[i]后插入一个与word2[j]相同的字符,即为 dp[i][j]==dp[i][j-1] + 1
在我们逐个比较的过程中,需要从这三种操作中选一种,让最后dp[i][j]最小,可以得到一个关系:
dp[i][j] = min{ dp[i][j]==dp[i-1][j-1], dp[i][j]==dp[i-1][j], dp[i][j]==dp[i][j-1] } + 1
找初始值
当 i 或 j 为0时,关系式就不在成立,不能进行移位。但是计算也很简单,其中一个为0时,另一个的长度就是最少的操作数。
public int func(String word1,String word2){
int len1 = word1.length();
int len2 = word2.length();
int[][] dp = new int[len1 + 1][len2 + 1];
//初始值dp[i][j]
for(int j = 1; j <= len2; j++){
dp[0][j] = dp[0][j-1] + 1;
}
for(int i = 1; i <= len1; i++){
dp[i][0] = dp[i-1][0] + 1;
}
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{
dp[i][j] = Math.min(Math.min(dp[i - 1][j - 1],
dp[i][j - 1]),
dp[i - 1][j]) + 1;
}
}
}
return dp[len1][len2];
}

浙公网安备 33010602011771号