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
一刷
题解:
首先我们考虑边界条件,当有一个string为空的时候我们返回0。
接下来创建一个dp矩阵dist,假如word1的长度为word1Len,word2的长度为word2Len,那么这个矩阵的长度就为[word1Len + 1, word2Len + 1]。
我们初始化第一行和第一列,dist[i][0] = i, dist[0][j] = j, 都是负责处理其中一个word为空这种情况。
接下来,我们定义dist[i][j]为 word1(0, i) 到word2(0,j) 这两个单词的min Edit distance。那么我们有以下的公式:
- 假如word1.charAt(i) == word2.charAt(j),那么dist[i][j] = 0
- 否则dist[i][j] = 1 + min (dist[i - 1][j - 1], min(dist[i - 1][j], dist[i][j - 1]))。
- 这里假如使用dist[i - 1][j - 1],意思是replace
- 假如使用dist[i - 1][j],那么是word1比word2少1个字符。 对word1来说是add
- 假如使用dist[i][j - 1],那么是word2比word1多一个字符。对word1来说是delete
最后返回结果dist[word1Len][word2Len]
优化:rolling array, 可以讲space complexity 由O(nm)降到O(n)
public class Solution {
public int minDistance(String word1, String word2) {
if(word1 == null || word2 == null) return 0;
int word1Len = word1.length(), word2Len = word2.length();
int[][] dist = new int[word1Len+1][word2Len+1];
for(int i=1; i<=word1Len; i++){
dist[i][0] = i;
}
for(int j=1; j<=word2Len; j++){
dist[0][j] = j;
}
for(int i=1; i<=word1Len; i++){
for(int j=1; j<=word2Len; j++){
if(word1.charAt(i-1) == word2.charAt(j-1)){
dist[i][j] = dist[i-1][j-1];
}
else{
//replace or delete/insert
dist[i][j] = Math.min(dist[i - 1][j - 1], Math.min(dist[i - 1][j], dist[i][j - 1])) + 1;
}
}
}
return dist[word1Len][word2Len];
}
}