我对leetcode 72的递归方法感到茫然

时间:2018-05-20 15:31:26

标签: c++ string recursion

虽然它会是TLE,但我认为理解使用动态编程的有效解决方案很有用,这里是描述和代码:

给出两个单词word1和word2,找到将word1转换为word2所需的最小步骤数。 (每个操作计为1步。) 您对单词允许以下3个操作: a)插入一个角色 b)删除一个角色 c)替换字符

int minDistance(string word1, string word2) {
        if(word1 == word2) return 0;

        int m = word1.size();
        int n = word2.size();

        if(word1 == "")
        {
            return n;
        }

        if(word2 == "")
        {
            return m;
        }

        if(word1[0] == word2[0])
        {
            return minDistance(word1.substr(1), word2.substr(1));
        }
        else
        {
            return min(1 + minDistance(word1, word2.substr(1)), min(1 + minDistance(word1.substr(1), word2), 1 + minDistance(word1.substr(1), word2.substr(1))));
        }

    }

一个问题是我无法理解ELSE结构的含义 - 在我看来,它有三种不同的情况,所以我猜它分别实现了插入 删除替换(可能订单不正确) 另一个是如何理解当一个字符串为空时,结果将是另一个字符串的长度?

1 个答案:

答案 0 :(得分:0)

return 
min
(
1 + minDistance(word1, word2.substr(1)), <-insert from word2
1 + minDistance(word1.substr(1), word2), <-delete from word1
1 + minDistance(word1.substr(1), word2.substr(1)) <-replace
)  

首先,
“insert”情况意味着我们从word2中取出第一个字符并将其插入到word1中(并增加“编辑距离”成本),这使我们留下了word1和word2.substr(1)

“删除”情况意味着我们抛弃了word1的第一个字符(并增加了“编辑距离”成本),这使我们留下了word1.substr(1)和word2

“替换”情况意味着两个单词的第一个字符是不同的,所以我们增加“编辑距离”成本并丢弃第一个字符,它们留给我们word1.substr(1)和word2.substr(1)< / p>

“相同”的情况意味着两个单词的第一个字符是相同的,所以我们不需要增加“编辑距离”成本,因此我们只丢弃第一个字符,它留给我们word1.substr(1 )和word2.substr(1)

因此我们有三种不同的可能性来检查,这就是为什么我们递归调用所有3个案例的函数,并通过拿起最小的一个来比较它们的最终成本。

其次,
基本情况“返回n”意味着为了将空字符串转换为word2,我们肯定需要将word2中的n个字符插入到word1中,将“n”添加到“编辑距离”成本
类似地,基本情况“返回m”意味着为了将word1转换为空字符串,我们肯定需要从word1删除m个字符,将“m”添加到“编辑距离”成本

您的算法是更通用的“编辑距离”算法的特例,可以通过修改插入/删除/替换/相同的成本来应用于广泛的问题。对于您的具体情况,目标是找到将word1转换为word2所需的最小步骤数,因此“insert / delete / replace”的cost = 1和“same”的cost = 0将是解决方案。

关于算法的动态编程版本,一旦定义了递归和必要的基本情况,就可以直接推导出它。