解题思路:
- 知道用dp,那么dp[i][j]表示在动态规划过程中表示字符串s1走到i位置,以及字符串s2走到j位置,所需要的最短字符串距离(需要修改的最小次数)
- 一般情况下,dp[i][j]应该是通过三种操作(插入一个字符,删除一个字符,以及修改一个字符)得到的最小操作次数,先要判断一下s1[i]==s2[j],如果相等则dp[i][j]=dp[i−1][j−1],否则有dp[i][j]=min(dp[i−1][j],dp[i−1][j−1],dp[i][j−1])+1。
- 再来处理边界情况,第一当i== 0 and j == 0时只需判断dp[0][0]=s1[i]==s2[j]? 0 : 1,接下来判断i==0时,判断s2[0−j]上是否存在s1[0],如果存在则最小距离为j,否则为j+1--即s2多出来部分的长度,同样的道理处理j==0时s1的剩余部分长度。
#include<bits/stdc++.h>
using namespace std;
int solve(string &s1, string &s2, int i, int j, vector<vector<int>> &dp){
if(dp[i][j] != -1) return dp[i][j];//如果已经计算直接返回
int flag;
//处理边界
if(i == 0 && j == 0) dp[i][j] = s1[i] != s2[j];
else if(i == 0){
int flag = 0;
for(int l = 0; l <= j; ++l){
if (s1[i] == s2[l]) {
flag = 1;
break;
}
}
if(flag) dp[i][j] = j;
else dp[i][j] = j + 1;
}
else if(j == 0){
int flag = 0;
for(int l = 0; l <=i; ++l){
if (s1[l] == s2[j]) {
flag = 1;
break;
}
}
if (flag) dp[i][j] = i;
else dp[i][j] = i+1;
}
else{//一般情况
if(s1[i] == s2[j]) dp[i][j] = solve(s1, s2, i-1,j-1,dp);
else dp[i][j] = min(solve(s1,s2,i-1,j-1,dp),min(solve(s1,s2,i-1,j,dp), solve(s1,s2,i,j-1,dp)))+1;
}
return dp[i][j];
}
int main(){
string s1;
string s2;
cin>>s1;
cin>>s2;
vector<vector<int>> dp(s1.size(), vector<int>(s2.size(),-1));
cout<<solve(s1, s2,s1.size()-1,s2.size()-1, dp)<<endl;
return 0;
}