一维动态规划:爬楼梯;二维动态规划:编辑距离
第一次根据思路写程序,在字符串如何切片,取[1:]被卡住了:
class Solution {
public:
int minDistance(string word1, string word2) {
}
private:
int minDistanceRecu(string word1, string word2) {
if(word1 == "") return word2.size();
if(word2 == "") return word1.size();
if(word1[0] == word2[0]) return minDistanceRecu(word1[], word2[]);
}
};
方法一:记忆化递归 + padding
需要加padding的一个主要原因,我认为是:两个字符串长度 l1,l2 ,比较字符串距离时可以从长度 0--l1 和 0--l2 范围内比较。
即分别是 l1+1 和 l2+1维。
class Solution {
public:
int minDistance(string word1, string word2) {
int l1 = word1.length();
int l2 = word2.length();
//vector<vector<int>> d_ = vector<vector<int>> (l1, vector<int>(l2));
d_ = vector<vector<int>> (l1+1, vector<int>(l2+1, -1)); //l1++1 * l2+1矩阵,初始值-1,用了padding的技巧
return minDistanceRecu(word1, word2, l1, l2);
}
private:
vector<vector<int>> d_;
int minDistanceRecu(const string& word1, const string& word2, int l1, int l2) {
if(l1==0) return l2;
if(l2==0) return l1;
if(word1[l1-1] == word2[l2-1]) return minDistanceRecu(word1, word2, l1-1, l2-1); //bug2:漏掉了:-1 长度为l1的字符串最后的索引是l1-1
if(d_[l1][l2]>=0) return d_[l1][l2];
d_[l1][l2] = min(minDistanceRecu(word1, word2, l1-1, l2),
min(minDistanceRecu(word1, word2, l1, l2-1),
minDistanceRecu(word1, word2, l1-1, l2-1))) + 1; //bug1:min只允许传入两个参数
return d_[l1][l2];
}
};
方法二:循环递推 + padding
同样是预先申请d(l1, l2)大小的矩阵存放循环结果
bug:一开始把 d[i-1][j] 打成了 d[i-1, j],因此会报错 error: no match for 'operator+' (operand types are 'const std::vector<int>' and 'int') 看了很久都没有发现这个错误,对比了别人的正确代码才看出来。
class Solution {
public:
int minDistance(string word1, string word2) {
int l1 = word1.length();
int l2 = word2.length();
vector<vector<int>> d(l1+1, vector<int>(l2+1, 0)); //定义编辑距离矩阵d
for(int i=0; i<=l1; i++) {
d[i][0] = i;
}
for(int j=0; j<=l2; j++) {
d[0][j] = j;
}
for(int i=1; i<=l1; i++) {
for(int j=1; j<=l2; j++) {
//word1(0,i-1) 和 word2(0,j-1)之间的编辑距离
int c = word1[i-1]==word2[j-1] ? 0 : 1;
d[i][j] = min( d[i-1][j-1]+c, min(d[i-1][j], d[i][j-1])+1 ); //error: no match for 'operator+' (operand types are 'const std::vector<int>' and 'int')
}
}
return d[l1][l2];
}
};
20.4.7再次做这道题又遇到一次错误:i, j 索引忘记建减一的问题
class Solution {
public:
int minDistance(string word1, string word2) {
const int n = word1.length(), m = word2.length();
vector<vector<int>> dp(n+1, vector<int>(m+1, 0));
//初始化base case
for(int i = 0; i <= n; i++)
dp[i][0] = i;
for(int i = 1; i <= m; i++)
dp[0][i] = i;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
if(word1[i-1] == word2[j-1]) { //这里应为 i-1, j-1这样范围才是0-n-1, 0-j-1;
dp[i][j] = dp[i-1][j-1];
}
else {
dp[i][j] = min(dp[i-1][j], min(dp[i][j-1], dp[i-1][j-1])) + 1;
}
}
}
return dp[n][m];
}
};