《算法设计与分析》第九周作业
标签(空格分隔): 课堂作业
姓名:李**
学号:16340114
题目:Edit Distance(https://leetcode.com/problems/edit-distance/description/)
题目概要
给定两个字符串,每次可以对增加、删除、替换一个字符。问最少多少次操作后,两个字符串变得一样。
思路
这个问题书本里有将过。思路就是将当前问题化解为若干个子问题去解决,取子问题中的最有解。子问题的情况有三:
[设i为字符串1的长度,j为字符串2的长度]
(i)string1的前(i-1)个字符与string2经过一定操作后可以变得一样,此时只需删掉string1的第i个字符
(ii)string2的前(j-1)个字符与string1经过一定操作后可以变得一样,此时只需删掉string2的第j个字符
(iii)string1的前(i-1)个字符与string2的前(j-1)个字符经过一定操作后可以变得一样,此时判断string1的第i个字符与string2的第j个字符是否相同,若不相同即进行替换操作,相同即不进行任何操作
这样,得到了状态转换方程(引自书本Algorithms(Dasgupta)):
具体实现
先初始化一个字符串为空,另一个字符串有字符的情况
再根据状态迁移方程编程即可(引自书本Algorithms(Dasgupta)):
需要注意,diff中的i, j是指第几个元素,实现时需要转换成字符串下标,减去一即可。
心得
重新复习了一遍书中的例子,并亲手编程之后,可算是有一点点领悟到动态规划的内涵了。动态规划的主要思想就是把当前的问题化解为一个或多个类似的子问题,就像领导布置工作给下属,下属又继续把工作分配给下属的下属,如此往复,当最下层的工作完成了,就逐层往上汇报,最后领导就得到一个完整的工作结果了。虽然比喻得可能不是很恰当,但大概也就是这个意思了吧。
源码:
class Solution
{
public:
int minDistance(string word1, string word2)
{
int m = word1.length();
int n = word2.length();
int** E = new int* [m+1];
for (int i = 0; i <= m; ++i)
E[i] = new int [n+1];
for (int i = 0; i <= m; ++i)
E[i][0] = i;
for (int j = 0; j <= n; ++j)
E[0][j] = j;
for (int i = 1; i <= m; ++i)
for (int j = 1; j <= n; ++j)
E[i][j] = min(E[i-1][j] + 1, E[i][j-1] + 1, E[i-1][j-1] + (word1[i-1] != word2[j-1]));
return E[m][n];
}
int min(int a, int b, int c)
{
int min = a;
if (b < min)
min = b;
if (c < min)
min = c;
return min;
}
};