问题
例子
思路
动态规划【最少操作数】
-
方法1
状态转移方程:dp[i][j] word1前长度i->word2前长度j的操作数
初始时:dp[0][j]=j, dp[i][0]=i
d p [ i ] [ j ] = { d p [ i − 1 ] [ j − 1 ] w o r d 1 [ i − 1 ] = = w o r d 2 [ j − 1 ] 1 + m i n ( d p [ i − 1 ] [ j − 1 ] , d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ) w o r d 1 [ i − 1 ] ! = w o r d 2. [ j − 1 ] dp[i][j]=\begin{cases}\\ dp[i-1][j-1]~~word1[i-1]==word2[j-1]\\ \\ 1+min(dp[i-1][j-1],dp[i-1][j], dp[i][j-1)~~word1[i-1]!=word2.[j-1]\\ \end{cases} dp[i][j]=⎩⎪⎨⎪⎧dp[i−1][j−1] word1[i−1]==word2[j−1]1+min(dp[i−1][j−1],dp[i−1][j],dp[i][j−1) word1[i−1]!=word2.[j−1]
对单词可以有三种操作: -
dp[i-1][j-1]->dp[i][j]:表修改
先把word1前i-1个变成word2前j-1个,此时word1的长度为j-1,然后把word1的第i个变为word2的第j个
-
dp[i][j-1]->dp[i][j]:表添加
先把word1前i个变成word2前j-1个,此时word1的长度为j-1,然后补上word2的第j个
-
dp[i][j-1]->dp[i][j]:删除
先把word1前i-1个变成word2前j个,此时word1的长度为j+1,然后删除掉word1的最后一个元素
-
方法2
$$$$
代码
//方法1
class Solution {
public int minDistance(String word1, String word2) {
int m = word1.length(),n=word2.length();
int[][] dp = new int[1+m][1+n];
//初始状态
for(int i=1; i<=m; i++)
dp[i][0]=i;
for(int i=1; i<=n; i++)
dp[0][i]=i;
for(int i=1; i<=m; i++) {
for(int j=1; j<=n; j++) {
if(word1.charAt(i-1)==word2.charAt(j-1))
dp[i][j]=dp[i-1][j-1];
else
dp[i][j]=1+Math.min(dp[i-1][j-1],Math.min(dp[i][j-1],dp[i-1][j]));
}
}
return dp[m][n];
}
}
//方法2