题目
Given two words word1 and word2, find the minimum number of operations required to convert word1 to word2.
You have the following 3 operations permitted on a word:
- Insert a character
- Delete a character
- Replace a charactetr
具体的例子看原题描述吧。
分析
其实这道题被分配到动态规划的大类里面,已经说明了解题思路了。其实不看答案我也不知道可以这样做。基本的思想是这样的,维护一个二维数组dp,dp[i][j]表示长度为i的字符串转化为长度为j的字符串所需要的最小改动个数。下标为0表示空串。这样一来,二维数组的第一行和第一列就很容易填充了,因为空串到其他字符串的最小改动次数都等于其他字符串的长度。与经典的动态规划解法一样,剩下的就是填充dp的其他部分了。这里是一般想不到的地方:
1、如果两个字符串的最后一个字符相同的话,那么从串a到串b的最小改动次数等于串a串b都去掉最后一个字符的最小改动次数。
即dp[i][j] = dp[i-1][j-1].
2、如果最后一个字符不同的话,那么从串a到串b的最小改动次数,需要从这三种情况里面选取。串a去最后一个字符到串b,串a 去最后一个字符到串b去最后一个字符,串a到串b去最后一个字符,取这3者的最小值然后+1即可。
整个过程从0分别对串a和串b一个字符一个字符的增加长度,记录下最小转化字符数。最终增加到长度与word1与word2相同时,便得到了结果。
代码
class Solution {
public:
int minDistance(string word1, string word2) {
int s1 = word1.size();
int s2 = word2.size();
int dp[s1+1][s2+1];
dp[0][0] = 0;
for(int i=1;i<=s1;i++)
dp[i][0] = i;
for(int i=1;i<=s2;i++)
dp[0][i] = i;
for(int i=1;i<=s1;i++)
for(int j=1;j<=s2;j++)
{
if(word1[i-1]==word2[j-1]) dp[i][j] = dp[i-1][j-1];
else dp[i][j] = min(dp[i-1][j],min(dp[i-1][j-1],dp[i][j-1]))+1;
}
return dp[s1][s2];
}
};