72.距離編集(ハード)
コード:
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 関数は比較対象として2 つの変数しか受け取れないため、3 つの変数を比較するとエラーが発生します。
さらに、上記の 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 分岐を 1 つ少なく書くことができます。次のように
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];
}