(此题也是计算所 VIPL 2024 考核机试题)

给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数 。

你可以对一个单词进行如下三种操作:

1.插入一个字符
2.删除一个字符
3.替换一个字符

输入:

sfdxbqw

gfdgw

输出:

4


这道题可以转化为二维动态规划问题。

假设 word1 长度为 m,word2 长度为 n。创建一个 (m+1)∗(n+1)(m + 1) * (n + 1) 的二维数组 dp。

dp[i][j] 代表把 word1 的前 i 个字符变成 word2 的前 j 个字符的最少操作数。

状态转移可以分两种情况考虑:

1.当 word1 的第 i 个字符与 word2 的第 j 个字符相同时,dp[i][j] 就等于 dp[i - 1][j - 1]。
2.不同时取上一个状态三种情况的最小值 + 1,即 dp[i - 1][j](插入)、dp[i][j - 1](删除)、dp[i - 1][j - 1](修改)。

C++26 linesExpandCollapse
#include <bits/stdc++.h>
using namespace std;

int main() {
    string s1, s2;
    cin >> s1;
    cin >> s2;
    
    int m = s1.size();
    int n = s2.size();
    
    vector<vector<int>> dp(m + 1, vector<int>(n + 1));
    
    for (int i = 0; i <= m; i++) dp[i][0] = i;
    for (int j = 0; j <= n; j++) dp[0][j] = j;
    
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            if (s1[i - 1] == s2[j - 1]) dp[i][j] = dp[i - 1][j - 1];
            else dp[i][j] = min{dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]} + 1;
        }
    }
    cout << dp[m][n] << endl;
    
    return 0;
}