Link: https://oj.leetcode.com/problems/edit-distance/
Below is my 1st attempt. But has errors.
public class Solution {
public int minDistance(String word1, String word2) {
if(word1 == null && word2 == null) return 0;
int m = word1.length();
int n = word2.length();
int[][] f = new int[m][n];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
int score = word1.charAt(i) == word2.charAt(j) ? 1 : 0;
f[i][j] = Math.min(Math.min(f[i-1][j], f[i][j-1])+1, f[i-1][j-1] + score);
}
}
return f[m-1][n-1];
}
}
Approach I: correct answer
Time: O(mn), Space: O(mn)
public class Solution {
public int minDistance(String word1, String word2) {
if(word1 == null && word2 == null) return 0;
int m = word1.length();
int n = word2.length();
int[][] f = new int[m+1][n+1];
//init the first row
for(int j = 0; j <=n; j++){
f[0][j] = j;
}
//init the first col
for(int i = 0; i <=m; i++){
f[i][0] = i;
}
//fill in the middle
for(int i = 1; i <=m; i++){
for(int j = 1; j <=n; j++){
if(word1.charAt(i-1) == word2.charAt(j-1)){
f[i][j] = f[i-1][j-1];//why don't need to compare with Math.min(f[i-1][j], f[i][j-1])+1 here?
}
else{
f[i][j] = Math.min(Math.min(f[i-1][j], f[i][j-1]), f[i-1][j-1])+1;
}
}
}
return f[m][n];
}
}
Approach II: DP with two arrays
Since f[i][j] come from f[i-1][j-1], f[i][j-1] and f[i-1][j], we cannot use one array to store it. So we create two arrays. One to store the current row, the other to store the previous row.
Time: O(mn), Space: O(min(m, n))
public class Solution {
public int minDistance(String word1, String word2) {
if(word1 == null && word2 == null) return 0;
int m = word1.length();
int n = word2.length();
int[] f = new int[n+1];
//init the first row
for(int j = 0; j <=n; j++){
f[j] = j;
}
//fill in the middle
for(int i = 1; i <=m; i++){
int[] newF = new int[n+1];
newF[0] = i;
for(int j = 1; j <=n; j++){
if(word1.charAt(i-1) == word2.charAt(j-1)){
newF[j] = f[j-1];
}
else{
newF[j] = Math.min(Math.min(f[j], newF[j-1]), f[j-1])+1;
}
}
f = newF;
}
return f[n];
}
}