题目的主要信息:
- Levenshtein 距离,指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数,编辑可包括将一个字符替换成另一个字符,插入一个字符,删除一个字符
- 给定任意两个字符串,计算二者的编辑距离
方法一:动态规划
具体做法:
我们用二维dp数组记录编辑距离,其中表示字符串s1前个字符与字符串s2前个字符之间的编辑距离。
初始状态时,s1中第0个字符与s2中每个字符的距离就是s2每个字符为止的长度,s2中第0个字符与s1中每个字符的距离就是s1每个字符为止的长度,因此二维数组第1行第1列分别置为相应的列号和行号。
后面我们对于字符串s1中从1到每个长度,都计算相应的到字符串2从1到每个长度的距离。转移方程为:
其中表示字符串s1前个字符到字符串s2前个字符的距离,增加一个字符即可得到,表示字符串s1前个字符到字符串s2前个字符的距离, 删除一个字符即可得到,因此转移都是加1次操作。表示字符串s1前个字符到字符串s2前个字符的距离,如果现在两个字符相同,则不变,否则增加一次修改操作,距离加1.
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
string s1, s2;
while(cin >> s1 >> s2){
int n = s1.length();
int m = s2.length();
vector<vector<int> > dp(n + 1, vector<int>(m + 1, 0)); //dp[i][j]表示s1中前i个字符与s2中前j个字符的距离
for(int i = 1; i <= m; i++) //s1中第0个字符与s2中每个字符的距离就是s2每个字符为止的长度
dp[0][i] = i;
for(int i = 1; i <= n; i++) //s2中第0个字符与s1中每个字符的距离就是s1每个字符为止的长度
dp[i][0] = i;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
int temp = dp[i - 1][j - 1];
if(s1[i - 1] != s2[j - 1]) //如果前两个字符不同,要多增加1的距离
temp++;
dp[i][j] = min(temp, min(dp[i - 1][j], dp[i][j - 1]) + 1); //状态转移,选出最小
}
}
cout << dp[n][m] << endl;
}
return 0;
}
复杂度分析:
- 时间复杂度:,其中和分别为两个字符串的长度,两层遍历
- 空间复杂度:,辅助数组dp的大小
方法二:动态规划空间优化
具体做法:
我们发现方法一在遍历的时候二维数组只使用到了本行及上一行,因为我们可以使用滚动数组优化(,表示行),每次遍历都只有两行,而下标在不断交替使用。每行首列在外循环进入的时候初始化为行号,原理同上。
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
string s1, s2;
while(cin >> s1 >> s2){
int n = s1.length();
int m = s2.length();
vector<vector<int> > dp(2, vector<int>(m + 1, 0)); //dp[i][j]表示s1中前i个字符与s2中前j个字符的距离,滚动数组表示
for(int i = 1; i <= m; i++) //s1中第0个字符与s2中每个字符的距离就是s2每个字符为止的长度
dp[0][i] = i;
int k = 0;
for(int i = 1; i <= n; i++){
k = 1 - k; //数组交换行
dp[k][0] = i; //初始置为该行号
for(int j = 1; j <= m; j++){
int temp = dp[1 - k][j - 1];
if(s1[i - 1] != s2[j - 1]) //如果这两个字符不同,要多增加1的距离
temp++;
dp[k][j] = min(temp, min(dp[1 - k][j], dp[k][j - 1]) + 1); //状态转移,选出最小
}
}
cout << dp[k][m] << endl;
}
return 0;
}
复杂度分析:
- 时间复杂度:,其中和分别为两个字符串的长度,两层遍历
- 空间复杂度:,辅助数组dp只有两行,每行长度