0 问题介绍
给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
- 插入一个字符(insertion)
- 删除一个字符(deletion)
- 替换一个字符(Substitution)
例如
w1="kitty", 2="puittys". w1->w2的编辑距离如下
- kitty->pitty,替换k->s
- pitty->puitty ,插入u
3.puitty->puittys,插入s
所以->
的编辑距离为3.
1 数学解答
我们定义两个字符串和
,它们的长度分别是
,
->
的编辑距离为
. 其中i和j分别表示w1和w2中前
个和前
个字符串截取,那么
和
的编辑距离可以用以下数学公式描述:
对于该数学公式描述如下:
1.表示的是字符串
和
中前
个字符和前
个字符的编辑距离,字符串的下标index从0开始。我们求得最后的编辑距离时
2.当时,证明我们截取的
(记作
)存在空串,此时的编辑距离就是
,也就是插入或删除
内的所有内容。
3.当时,
为以下三个值中的最小值:
-,删除
.
-,在
的位置插入
.
-,替换
为
.
-,
.
4.为了控制最后的的变化,增加辅助函数
通过分析,我们很容易就发现这个算法也是由多个重叠的子问题构成的,所以我们要计划使用递归和动态规划两种算法对该问题进行解决。
2 实例演示
"
",
="
"
/ | 空 | 0a | 1b | 2c |
---|---|---|---|---|
空 | ||||
0a | ||||
1d | ||||
2c | ||||
3t |
步骤1:初始化第一行第一列
依照公式
/ | 空 | 0a | 1b | 2c |
---|---|---|---|---|
空 | 0 | 1 | 2 | 3 |
0a | 1 | |||
1d | 2 | |||
2c | 3 | |||
3t | 4 |
步骤2:依照公式完全矩阵
/ | 空 | 0a | 1b | 2c |
---|---|---|---|---|
空 | 0 | 1 | 2 | 3 |
0a | 1 | 0 | 1 | 2 |
1d | 2 | 1 | 1 | 2 |
2c | 3 | 2 | 2 | 1 |
3t | 4 | 3 | 3 | 2 |
3 代码实现(PHP)
3.1 递归实现
class Solution {
/**
* @param String $word1
* @param String $word2
* @return Integer
*/
function minDistance($word1, $word2) {
if (strlen($word1)==0)
return strlen($word2);
else if (strlen($word2)==0)
return strlen($word1);
else if ($word1==$word2)
return 0;
if ($word1[strlen($word1)-1]==$word2[strlen($word2)-1])
$d=0;
else
$d=1;
return min($this->minDistance(substr($word1,0,strlen($word1)-1),$word2)+1,
$this->minDistance($word1,substr($word2,0,strlen($word2)-1))+1,
$this->minDistance(substr($word1,0,strlen($word1)-1),substr($word2,0,strlen($word2)-1))+$d);
}
}
class Solution {
/**
* @param String $word1
* @param String $word2
* @return Integer
*/
function minDistance($word1, $word2) {
$LenOfWord1=strlen($word1);
$LenOfWord2=strlen($word2);
if ($LenOfWord1==0)
return $LenOfWord2;
else if ($LenOfWord2==0)
return $LenOfWord1;
else if ($word1==$word2)
return 0;
if ($word1[$LenOfWord1-1]==$word2[$LenOfWord2-1])
$d=0;
else
$d=1;
return min($this->minDistance(substr($word1,0,$LenOfWord1-1),$word2)+1,
$this->minDistance($word1,substr($word2,0,$LenOfWord2-1))+1,
$this->minDistance(substr($word1,0,$LenOfWord1-1),substr($word2,0,$LenOfWord2-1))+$d);
}
}
结果在leetcode上写完提交,测试用例发现超时了,但是我也没发现题目哪里要求了时间。把strlen的结果存储起来,收效甚微。没办法,只好尝试使用动态规划。
3.2 动态规划
网友评论