学渣带你刷Leetcode0072编辑距离

题目描述

给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。

你可以对一个单词进行如下三种操作:

插入一个字符
删除一个字符
替换一个字符
 

示例 1:

输入:word1 = "horse", word2 = "ros"
输出:3
解释:
horse -> rorse (将 'h' 替换为 'r')
rorse -> rose (删除 'r')
rose -> ros (删除 'e')
示例 2:

输入:word1 = "intention", word2 = "execution"
输出:5
解释:
intention -> inention (删除 't')
inention -> enention (将 'i' 替换为 'e')
enention -> exention (将 'n' 替换为 'x')
exention -> exection (将 'n' 替换为 'c')
exection -> execution (插入 'u')

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/edit-distance
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

白话题目:
 

算法:

 

详细解释关注 B站  【C语言全代码】学渣带你刷Leetcode 不走丢 https://www.bilibili.com/video/BV1C7411y7gB

C语言完全代码

//方法二:动态规划算法
//1,使用 dp[m][n] 表示 word1 的m个字符 和 word2 的n个字符的最少操作数
//2,找到 dp[m][n] 和 dp[m-1][n-1] 、dp[m-1][n]、dp[m][n-1] 之间的关系
//3,发现 if(word1[m] == word2[n]) 则 dp[m][n]=1+MIN(dp[m-1][n-1]-1,dp[m-1][n],dp[m][n-1]);
//  从 dp[m-1][n-1]转变到 dp[m][n] 由于最后一个字符相等,所以操作数不用加一
//4,if(word1[m] != word2[n]) 则 dp[m][n]=1+MIN(dp[m-1][n-1],dp[m-1][n],dp[m][n-1]);

#define     MIN(a, b, c)    ((a) < ((b) < (c) ? (b) : (c)) ? (a) : ((b) < (c) ? (b) : (c)))
int minDistance(char * word1, char * word2){
    int     i       = 0;
    int     j       = 0;
    int     iLen1   = strlen(word1);
    int     iLen2   = strlen(word2);
    int     dp[iLen1 + 1][iLen2 + 1];

    //1,初始化
    for (i = 0; i <= iLen1; i++)
    {
        dp[i][0] = i;
    }
    for (j = 0; j <= iLen2; j++)
    {
        dp[0][j] = j;
    }

    //2,动态规划计算最终解
    for (i = 1; i <= iLen1; i++)
    {
        for (j = 1; j <= iLen2; j++)
        {
            if (word1[i - 1] == word2[j - 1])
            {
                dp[i][j] = 1 + MIN(dp[i-1][j-1] - 1, dp[i - 1][j], dp[i][j - 1]);
            }
            else
            {
                dp[i][j] = 1 + MIN(dp[i-1][j-1], dp[i - 1][j], dp[i][j - 1]);
            }
        }
    }

/*
    for (i = iLen1; i >= 0; i--)
    {
        for (j = 0; j <= iLen2; j++)
        {
            printf("%02d, ", dp[i][j]);
        }
        printf("\n");
    }
*/
    return dp[iLen1][iLen2];
}

/*
//方法一:回溯法
//每个字符有以下四种操作方法
//0,字符不变
//1,插入一个字符
//2,删除一个字符
//3,替换一个字符
#define     MAX(a, b)   ((a) > (b) ? (a) : (b))
#define     MIN(a, b)   ((a) < (b) ? (a) : (b))
int backTrackDistance(char* pWord1, char* pWord2, int* iMin, int iStep){
    int     iLen1       = strlen(pWord1);
    int     iLen2       = strlen(pWord2);
    int     iStepLen1   = iStep;
    int     iStepLen2   = iStep;
    int     iStepLen3   = iStep;
    int     iStepLen4   = iStep;
    int     iMinStep    = iStep;

    //1,结束条件
    if (((iLen1 == 0) && (iLen2 == 0)) || 
        ((iLen1 == iLen2) && (0 == memcmp(pWord1, pWord2, iLen1))))
    {
        //剩下两部分相同,不需要再操作
        if (iStep < *iMin)
        {
            *iMin = iStep;
        }
        iMinStep = iStep;
        return iMinStep;
    }

    //2,回溯操作
    if (pWord1[0] == pWord2[0])
    {
        //第一个字符相同,则字符不变,进行下一步
        iStepLen1 = backTrackDistance(&pWord1[1], &pWord2[1], iMin, iStep);
        iMinStep = MIN(iMinStep, iStepLen1);
    }

    if (iLen1 <= iLen2)
    {
        //word1 长度 < word2 长度,则插入一个字符
        iStepLen2 = backTrackDistance(&pWord1[0], &pWord2[1], iMin, iStep + 1);
        iMinStep = MIN(iMinStep, iStepLen2);
    }
    
    if (iLen1 >= iLen2)
    {
        //word1 长度 >word2 长度,则删除一个字符
        iStepLen3 = backTrackDistance(&pWord1[1], &pWord2[0], iMin, iStep + 1);
        iMinStep = MIN(iMinStep, iStepLen3);
    }

    if ((pWord1[0] != pWord2[0]) && (pWord1[0] != '\0') && (pWord2[0] != '\0'))
    {
        //替换一个字符
        iStepLen4 = backTrackDistance(&pWord1[1], &pWord2[1], iMin, iStep + 1);
        iMinStep = MIN(iMinStep, iStepLen4);
    }

    return iMinStep;
}

int minDistance(char * word1, char * word2){
    int     iLen1       = strlen(word1);
    int     iLen2       = strlen(word2);
    int     iMaxLen     = MAX(iLen1, iLen2);
    char*   pWord1      = NULL;
    char*   pWord2      = NULL;
    int     iMin        = iMaxLen;

    //1,初始化
    pWord1 = (char*)malloc(sizeof(char) * (iMaxLen + 1));
    memset(pWord1, 0x00, sizeof(char) * (iMaxLen + 1));
    memcpy(pWord1, word1, sizeof(char) * iLen1);

    pWord2 = (char*)malloc(sizeof(char) * (iLen2 + 1));
    memset(pWord2, 0x00, sizeof(char) * (iLen2 + 1));
    memcpy(pWord2, word2, sizeof(char) * iLen2);

    //2,回溯调用
    backTrackDistance(pWord1, pWord2, &iMin, 0);

    //3,释放空间
    free(pWord1);
    free(pWord2);

    //4,返回
    return iMin;
}
*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值