LeetCode解题方法5-动态规划求距离问题

1. 题目编号

?-简单距离问题
72-编辑距离(困难)

2.方法说明

采用动态规划思想,求出转移方程dp[i][j]=?。

3.简单距离问题

题目:

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

代码

bool isMatch(char * s, char * p){
    int i, j, len1, len2;
    len1 = strlen(s);
    len2 = strlen(p);
    bool** dp;
    dp = (bool**)malloc(sizeof(bool*) * (len1 + 1));
    for (i = 0; i < len1 + 1; i++) {
        dp[i] = (bool*)malloc(sizeof(bool) * (len2 + 1));
        memset(dp[i], 0, sizeof(bool) * (len2 + 1));
    }
    dp[0][0] = true;
    for (i = 0; i < len2; i++) {
        if (p[i] == '*' && i > 0 && dp[0][i - 1]) {
            dp[0][i + 1] = true;
        }
    }
    for (i = 0; i < len1; i++) {
        for (j = 0; j < len2; j++) {
            if (s[i] == p[j] || p[j] == '.') {
                dp[i + 1][j + 1] = dp[i][j];
                continue;
            }
            if (p[j] == '*' && j > 0) {
                if (s[i] == p[j - 1] || p[j - 1] == '.') {
                    dp[i + 1][j + 1] = dp[i][j + 1] || dp[i][j - 1] || dp[i + 1][j - 1];
                } else {
                    dp[i + 1][j + 1] = dp[i + 1][j - 1];
                }
            }
        }
    }
    return dp[len1][len2];
}

4.72题编辑距离

题目
给定两个单词 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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
由于该题用回溯方法会超时,只能用动态规划的方法。
先将复杂问题变简单,用dp[i][j]表示字符串word1的1至i,变化到字符串word2的1至j,最少需要多少步。
dp[i][j]的计算方法可以根据dp[i - 1][j - 1], dp[i][j - 1] , dp[i - 1][j],
当dp[i][j - 1]为x时,由于word2长度j-1变为j,word1变化至word2需要增加一次插入,次数为x+1
当dp[i - 1][j]为x时,由于word1长度i-1变为i,word1变化至word2需要增加一次删除,次数为x+1
当dp[i - 1][j - 1]为x,且word1[i ] == word2[j],word1变化至word2不需要增加变化次数,次数为x
当dp[i - 1][j - 1]为x,且word1[i ] != word2[j],word1变化至word2需要增加一次替换,次数为x+1

此外注意一下数组的边界,dp[i][0] = i和dp[0][j] = j
代码

#define MIN(a, b) ((a)<(b)?(a):(b))
int minDistance(char * word1, char * word2){
    int** dp;
    int i, j, len1, len2;
    len1 = strlen(word1);
    len2 = strlen(word2);
    if (len1 == 0 || len2 == 0) {
        return len1 + len2;
    }
    dp = (int**)malloc(sizeof(int*) * (len1 + 1));
    for (i = 0; i < len1 + 1; i++) {
        dp[i] = (int*)malloc(sizeof(int) * (len2 + 1));
        dp[i][0] = i;
    }
    for (j = 1; j < len2 + 1; j++) {
        dp[0][j] = j;
    }
    for (i = 1; i < len1 + 1; i++) {
        for (j = 1; j < len2 + 1; j++) {
            if (word1[i - 1] == word2[j - 1]) {
                dp[i][j] = MIN(MIN(dp[i - 1][j - 1], dp[i][j - 1] + 1), dp[i - 1][j] + 1);
            } else {
                dp[i][j] = MIN(MIN(dp[i - 1][j - 1] + 1, dp[i][j - 1] + 1), dp[i - 1][j] + 1);
            }
        }
    }
    return dp[len1][len2];
}

你可能感兴趣的:(LeetCode解题方法5-动态规划求距离问题)