Leetcode第583题 两个字符串的删除操作 C++解法

刚开始对这题毫无头绪,想了几分钟,才意识到可以用求最长公共子序列去做。只要求出LCS,size1+size2-2*LCS即为结果。

class Solution {
public:
int longestCommonSubsequence(string text1, string text2) {
    int dp[text2.size()+1],pre,temp,res=0;
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=text1.size();i++)
    {
        pre=dp[0];
        for(int j=1;j<=text2.size();j++)
        {
            temp=dp[j];
            if(text1[i-1]==text2[j-1])
                dp[j]=pre+1;
            else
                dp[j]=max(dp[j],dp[j-1]);
            res=max(dp[j],res);
            pre=temp;
        }
    }
    return res;
}
    int minDistance(string word1, string word2) {
        return word1.size()+word2.size()-2*longestCommonSubsequence(word1,word2);
    }
};

做完自己试着画网格分析了直接用动态回归去做(比较笨,只能用例子去归纳),得到下面的状态转移方程在这里插入图片描述
果不其然第一次出错

class Solution {
public:
    int minDistance(string word1, string word2) {
    int i,j,dp[word1.size()+1][word2.size()+1];
    for(i=1;i<=word2.size();i++)
    dp[0][i]=i+1;
    for(i=1;i<=word1.size();i++)
    dp[i][0]=i+1;//这里错误,应该是i。这里是因为一开始没有得到min+1的方程
    dp[0][0]=0;
    for(i=1;i<=word1.size();i++)
    {
        for(j=1;j<=word2.size();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],dp[i][j-1])+1;
        }
    }
    return dp[i-1][j-1];
    }
};

然而,纠正过一些语法之类的错误,后又报错了,因为没考虑空字符串的情况,没法只好打补丁了

class Solution {
public:
    int minDistance(string word1, string word2) {
    
    int m=word1.size(),n=word2.size();
    if(!m&&!n)  return 0;
    if(!m)  return n;
    if(!n)  return m;
    int i,j,dp[m+1][n+1];
    for(i=1;i<=n;i++)
    dp[0][i]=i;
    for(i=1;i<=m;i++)
    dp[i][0]=i;
    dp[0][0]=0;
    for(i=1;i<=m;i++)
        for(j=1;j<=n;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],dp[i][j-1])+1;
        }
    return dp[i-1][j-1];
    }
};

结果后面发现,其实开头的判断也不用,之所以遇到空数组出现问题,是我最后返回值有问题,我应该返回dp[m][n],之前忽略了空字符串不仅如此循环的情况。

    return dp[m][n];

但是当我想优化这个空间复杂度的时候,遇到了问题,咋弄也没法优化成功,又是打补丁,又是干其他的,都不行。后来发现状态转移方程给搞错了,当然dp[0]和pre的初始化也有问题。唉,在这淦了一个多小时!

class Solution
{
public:
    int minDistance(string word1, string word2)
    {

        int m = word1.size(), n = word2.size();
        int temp, pre, i, j, dp[n + 1];
        for (i = 0; i <= n; i++)
            dp[i] = i;
        for (i = 1; i <= m; i++)
        {
            pre=dp[0];
            dp[0]=dp[0]+1;
            for (j = 1; j <= n; j++)
            {
                temp = dp[j];
                if (word1[i - 1] == word2[j - 1])
                    dp[j] = dp[j - 1];
                else
                    dp[j] = min(dp[j - 1], pre) + 1;
                pre = temp;
            }
        }
        return dp[n];
    }
};

正确的O(n)方法
class Solution
{
public:
int minDistance(string word1, string word2)
{

    int m = word1.size(), n = word2.size();
    int temp, pre, i, j, dp[n + 1];
    for (i = 0; i <= n; i++)
        dp[i] = i;
    for (i = 1; i <= m; i++)
    {
        pre=dp[0];
        dp[0]=dp[0]+1;
        for (j = 1; j <= n; j++)
        {
            temp = dp[j];
            if (word1[i - 1] == word2[j - 1])
                dp[j] = pre;
            else
                dp[j] = min(dp[j - 1], dp[j]) + 1;
            pre = temp;
        }
    }
    return dp[n];
}

};

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值