LeetCode 72:编辑距离

18 篇文章 0 订阅

 一维动态规划:爬楼梯;二维动态规划:编辑距离

第一次根据思路写程序,在字符串如何切片,取[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];
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值