class Solution {
public:
int minDistance(string word1, string word2) {
int m = word1.size(),n = word2.size();
int l = lcs(word1,word2,m,n);
return m + n -2 * l;
}
private:
int lcs(string word1,string word2,int m,int n) {
if(m == 0 || n == 0) return 0;
if(word1[m - 1] == word2[n - 1]) {
return 1 + lcs(word1,word2,m - 1,n - 1);
} else {
return max(lcs(word1,word2,m-1,n),lcs(word1,word2,m,n-1));
}
}
};
使用lcs方法计算,如果存在最长公共子序列,那么两个字符串长度之和减去两份最长公共子序列长度,就是需要删除的次数,可惜的时程序执行Time Limit Exceeded,令人奇怪的时失败用例似乎并不复杂:
"dinitrophenylhydrazine"
"benzalphenylhydrazone"
尝试使用递归加记忆化方式,解决子问题重复计算的问题,上面失败的用例通过后,又会存在新的用例执行Time Limit Exceeded
class Solution {
public:
int minDistance(string word1, string word2) {
int m = word1.size(),n = word2.size();
vector<vector<int>> mem(m + 1,vector<int>(n + 1,0));
return m + n - 2 * lcs(word1,word2,m,n,mem);
}
private:
int lcs(string word1,string word2,int m,int n,vector<vector<int>> &mem) {
if(m == 0 || n ==0) return 0;
if(mem[m][n] > 0) return mem[m][n];
if(word1[m - 1] == word2[n - 1]) {
mem[m][n] = 1 + lcs(word1,word2,m - 1,n - 1,mem);
} else {
mem[m][n] = max(lcs(word1,word2,m-1,n,mem),lcs(word1,word2,m,n-1,mem));
}
return mem[m][n];
}
};
失败的case:
Last executed input
"tzwcgoozzzqpwdyvsbh"
"bsjfnmllccynlxgzqhysewtacutpoengqqqyup"
上面的代码其实存在一个小的待改进点,如果将vector初始化时默认值设置为-1,针对dp[i][j]==0的场景我们是不需要重复计算的,调整后的代码:
class Solution {
public:
int minDistance(string word1, string word2) {
int m = word1.size(),n = word2.size();
vector<vector<int>> mem(m+1,vector(n+1,-1));
return m + n - 2*lcs(word1,word2,m,n,mem);
}
private:
int lcs(string word1,string word2,int m ,int n,vector<vector<int>> & mem) {
if(m == 0 || n == 0)
return 0;
if(mem[m][n] >= 0)
return mem[m][n];
if(word1[m-1] == word2[n-1])
mem[m][n] = 1 + lcs(word1,word2,m-1,n-1,mem);
else
mem[m][n] = max(lcs(word1,word2,m,n-1,mem),lcs(word1,word2,m-1,n,mem));
return mem[m][n];
}
};
运行结果:
Runtime: 648 ms, faster than 5.04% of C++ online submissions for Delete Operation for Two Strings.
Memory Usage: 328.2 MB, less than 5.04% of C++ online submissions for Delete Operation for Two Strings.
常规动态规划算法求解(AC):
class Solution {
public:
int minDistance(string word1, string word2) {
int m = word1.size();
int n = word2.size();
//dp[i][j]表示word1[0---i]和word2[0---j]中最长公共子序列
vector<vector<int>> dp(m + 1,vector<int>(n + 1,0));
for(int i = 1;i <= m;i++) {
for(int j = 1;j <= n;j++) {
if(word1[i - 1] == word2[j - 1])
dp[i][j] = 1 + dp[i-1][j-1];
else
dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
}
}
return m+n-2*dp[m][n];
}
};