题目原文:
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)
You have the following 3 operations permitted on a word:
a) Insert a character
b) Delete a character
c) Replace a character
题目大意:
要把word1变成word2,总共分几步?
————赵本山小品台词迷之乱入。。。
每一步可以增加一个字符、减少一个字符、修改一个字符。求把字符串word1变成word2的最小步数。
题目分析:
设dp[i][j]表示把word1的前i个字符变成word2的前j个字符的最小步数,首先初始化dp[0][j]=j(显然如此,因为把空串变成一个长度为j的字符串只能增加),同理dp[i][0]=i.
接下来转移方程亦不难理解:考虑dp[i][j],如果word1[i]==word2[j],那么这一位就没变,只需要把前面的字符以最小步数变过来就可以,因此dp[i][j]=dp[i-1][j-1];如果不等,则只有三种情况:
(1) 把word1的前i-1个字符变成word2的前j-1个字符,再修改word1[i]为word2[j];
(2) 把word1的前i个字符变成word2的前j-1个字符,再加上word2[j];
(3) 把word1的前i-1的字符变成word2的前j个字符,再删除word[i]。
因此dp[i][j]=min(dp[i-1][j-1],dp[i][j-1],dp[i-1][j])+1.
源码:(language:java)
public class Solution {
public int minDistance(String word1, String word2) {
int len1 = word1.length(),len2 = word2.length();
int[][] dp = new int[len1+1][len2+1];
for (int i = 1; i<=len1; i++)
dp[i][0] = i;
for (int j = 1; j<=len2; j++)
dp[0][j] = j;
for (int i = 1;i<=len1;i++) {
for(int j = 1;j<=len2;j++) {
if(word1.charAt(i-1)!=word2.charAt(j-1)) {
int min = Math.min(dp[i-1][j], Math.min(dp[i-1][j-1], dp[i][j-1]));
dp[i][j] = min+1;
}
else
dp[i][j] = dp[i-1][j-1];
}
}
return dp[len1][len2];
}
}
成绩:
13ms,beats 63.16%,众数13ms,19.74%
Cmershen的碎碎念:
相传这个算法在斯坦福大学的NLP公开课上讲过,我也是在上学期的《计算机语言学》课上了解到这个算法的。既然先入为主了,我并不觉得这道题有Hard难度。(比之前面几题各种高级数据结构……匪夷所思的算法……)