72.编辑距离(hard)
代码:
class Solution {
public:
int minDistance(string word1, string word2) {
int n = word1.size(),m = word2.size();
vector<vector<int>>dp(n + 1,vector<int>(m + 1,0)); //dp数组,记录了word1到i位置,word2到j位置的最小步数
//dp数组边界的值?
for(int i = 0; i < n; ++i){
dp[i][0] = i;
}
for(int j = 0; j < m; ++j){
dp[0][j] = j;
}
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= m; ++j){
if(word1[i] == word2[j]){
dp[i][j] = dp[i - 1][j - 1];
}
else{
dp[i][j] = min(dp[i - 1][j] + 1,dp[i][j - 1] + 1, dp[i - 1][j - 1] + 1);
}
}
}
return dp[n][m];
}
};
这里可以看到,报错位置是min函数。
错误原因:
C++中的min函数只接收两个变量进行比较,如果三个变量进行比较就会出错。
另外上面的if比较也出错了!word1和word2会有越界!
正确代码
class Solution {
public:
int minDistance(string word1, string word2) {
int n = word1.size(),m = word2.size();
vector<vector<int>>dp(n + 1,vector<int>(m + 1,0)); //dp数组,记录了word1到i位置,word2到j位置的最小步数
//dp数组边界的值?
for(int i = 0; i <= n; ++i){
dp[i][0] = i;
}
for(int j = 0; j <= m; ++j){
dp[0][j] = j;
}
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= m; ++j){
if(word1[i-1] == word2[j-1]){
dp[i][j] = dp[i - 1][j - 1];
}
else{
dp[i][j] = min(dp[i - 1][j] + 1,min(dp[i][j - 1] + 1, dp[i - 1][j - 1] + 1));
}
}
}
return dp[n][m];
}
};
总结
初始条件的设置有一点不优雅。可以集成到总的for循环里面。然后for循环里面的if语句可以集成变成一个三目运算符,这样就可以少写一个if-else分支。如下
int minDistance(string word1, string word2) {
int m = word1.length(), n = word2.length();
vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
for (int i = 0; i <= m; ++i) {
for (int j = 0; j <= n; ++j) {
if (i == 0) {
dp[i][j] = j;
} else if (j == 0) {
dp[i][j] = i;
} else {
dp[i][j] = min(
dp[i-1][j-1] + ((word1[i-1] == word2[j-1])? 0: 1),
min(dp[i-1][j] + 1, dp[i][j-1] + 1));
}
}
}
return dp[m][n];
}