题目描述
知识点
编辑距离、字符串动态规划、二维数组
结果
实现
码前思考
- 这道题目是典型地从暴力解法里面提炼动态规划思想的问题。与背包问题有着异曲同工之妙~~都使用了二维的数组,都是递推实现的;
- 关于这道题目的详细的解题方案可以参见动态规划:编辑距离(Edit Distance)
代码实现
//使用动态规划进行解题
//使用二维数组进行求解动态规划问题
class Solution {
public:
vector<vector<int>> dp;
int minVal(int a,int b,int c){
return min(a,min(b,c));
}
int minDistance(string word1, string word2) {
int m = word1.size();
int n = word2.size();
dp.assign(m+1,vector<int>(n+1));
//动态规划,首先对边界条件进行初始化
for(int i=0;i<=m;i++){
dp[i][0] = i;
}
for(int j=0;j<=n;j++){
dp[0][j] = j;
}
//接下来进行递推,有状态转移方程可以得知,递推的顺序应该是自上而下,自左而右
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(word1[i-1] == word2[j-1]){
dp[i][j] = dp[i-1][j-1];
}else{
dp[i][j] = minVal(dp[i-1][j]+1,dp[i][j-1]+1,dp[i-1][j-1]+1);
}
}
}
return dp[m][n];
}
};
码后反思
- 其实编辑距离的解法就是在暴力枚举的基础上引入了重叠子问题的思想,使用
dp
数组来解决重叠子问题~ - 代码量好少,就是比较难想到这种纯暴力的元素做法!
二刷代码
省去了一些思维量的代码:
//使用动态规划进行解题
//使用二维数组进行求解动态规划问题
class Solution {
public:
vector<vector<int>> dp;
int minVal(int a,int b,int c){
return min(a,min(b,c));
}
int minDistance(string word1, string word2) {
int m = word1.size();
int n = word2.size();
dp.assign(m+1,vector<int>(n+1));
//动态规划,首先对边界条件进行初始化
for(int i=0;i<=m;i++){
dp[i][0] = i;
}
for(int j=0;j<=n;j++){
dp[0][j] = j;
}
//接下来进行递推,有状态转移方程可以得知,递推的顺序应该是自上而下,自左而右
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(word1[i-1] == word2[j-1]){
dp[i][j] = min(dp[i-1][j-1],dp[i-1][j]+1);
dp[i][j] = min(dp[i][j],dp[i][j-1]+1);
dp[i][j] = min(dp[i][j],dp[i-1][j-1]+1);
}else{
dp[i][j] = minVal(dp[i-1][j]+1,dp[i][j-1]+1,dp[i-1][j-1]+1);
}
}
}
return dp[m][n];
}
};