题目描述
解题思路
首先注意字符串s1[1…n]、s2[1…m] 的下标是从1开始的。
将字符串s1转换为s2的过程 与 将字符串从s2转换为s1的过程互 为逆过程,所需的编辑次数相同,因此只需要考虑一种情况即可。
定义状态dp[i][j]的含义为:将s1的前i个字符s1[1…i] 转换为 s2的前j个字符s2[1…j]所需的最少编辑次数。
状态转移规律:
- 如果
s1[i] == s2[j]
:因为最后一个字符相同,不需要改变,要将s1[1…i]转换为s2[1…j] 只需 将s1[1…i-1]转换为s2[1…j-1],即dp[i][j] = dp[i-1][j-1]
; - 如果
s1[i] != s2[j]
,dp[i][j]为下面三种情况中编辑次数最少的一个:- 先将s1[1…i-1]转换为s2[1…j-1],再将s1[i]修改为s2[j],所需编辑次数
dp[i-1][j-1]+1
- 先将s1[1…i-1]转换为s2[1…j],再删掉s1[i],所需编辑次数
dp[i-1][j]+1
- 先将s1[1…i]转换为s2[1…j-1],再在s1末尾加上s2[j],所需编辑次数
dp[i][j-1]+1
d p [ i ] [ j ] = m i n { d p [ i − 1 ] [ j − 1 ] + 1 d p [ i ] [ j − 1 ] + 1 d p [ i − 1 ] [ j ] + 1 } dp[i][j] = min\left\{ \begin{matrix} \begin{aligned} &dp[i-1][j-1]+1\\ &dp[i][j-1]+1\\ &dp[i-1][j]+1\\ \end{aligned} \end{matrix} \right\} dp[i][j]=min⎩ ⎨ ⎧dp[i−1][j−1]+1dp[i][j−1]+1dp[i−1][j]+1⎭ ⎬ ⎫
- 先将s1[1…i-1]转换为s2[1…j-1],再将s1[i]修改为s2[j],所需编辑次数
int dp[1001][1001];
int solve(){
// init
// dp[0][j]
for(int j=0; j<m; j++){
dp[0][j] = j; // 向s1中添加j个字符
}
// dp[i][0]
for(int i=0; i<n; i++){
dp[i][0] = i; // 删掉s1中的i个字符
}
// bottom-up calc
for(int i=1; i<n; i++){
for(int j=1; j<m; j++){
if(s1[i] == s2[j]){
dp[i][j] = dp[i-1][j-1];
}else{
dp[i][j] = min(dp[i-1][j-1]+1,
min(dp[i-1][j]+1,
dp[i][j-1]+1));
}
}
}
return dp[n-1][m-1];
}