問題描述
https://leetcode.com/problems/edit-distance/#/description
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
,可以有三種操作,刪除、替換、增加一個字符,每執行一次算作一次操作,返回至少需要多少次操作。
算法
使用動態規劃,設f(i,j)
表示將word1
的前i個字符轉化爲word2
的前j個字符,設n=word1.length()
, m=word2.length()
,則最終的結果就是求:f(n, m)
下面是動態轉移方程:
- 初始條件,
f(0,k) = f(k,0) = k
,f(0,k)=k
表示將word1
的前0
個字符轉換爲word2
的前k
個字符所需操作數,因爲是從0
個字符變換爲k
個字符,自然需要k
次操作 word1[i] = word2[j]
時,有f(i,j) = f(i-1,j-1)
,因爲此時不需要操作,所以操作次數與前面的變換次數相等word2[i] != word2[j]
時,有f(i,j) = 1 + min{f(i,j-1)
,f(i-1,j)
,f(i-1,j-1)}
,f(i,j-1)
表示insert
,f(i-1,j)
表示delete
,f(i-1,j-1)
表示replace
時間複雜度O(nm)
代碼
public class Solution {
/**
* 將word1變爲word2,可以有三種操作,刪除、替換、增加一個字符,每執行一次算作一次操作,返回至少需要多少次操作。
* 算法:
* 使用動態規劃,設f(i,j)表示將word1的前i個字符轉化爲word2的前j個字符,設n=word1.length(), m=word2.length(),則最終的結果就是求:f(n, m)
* 下面是動態轉移方程:
* 1. 初始條件,f(0,k) = f(k,0) = k,f(0,k)=k表示將word1的前0個字符轉換爲word2的前k個字符所需操作數,因爲是從0個字符變換爲k個字符,自然需要k次操作
* 2. word1[i] = word2[j]時,有f(i,j) = f(i-1,j-1),因爲此時不需要操作,所以操作次數與前面的變換次數相等
* 3. word2[i] != word2[j]時,有f(i,j) = 1 + min{f(i,j-1), f(i-1,j), f(i-1,j-1)},f(i,j-1)表示insert, f(i-1,j)表示delete,f(i-1,j-1)表示replace
*/
public int minDistance(String word1, String word2) {
int n = word1.length();
int m = word2.length();
int[][] f = new int[n+1][m+1];
for(int i=0;i<=m;i++) {
f[0][i] = i;
}
for(int i=0;i<=n;i++) {
f[i][0] = i;
}
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
if(word1.charAt(i-1) == word2.charAt(j-1)) {
f[i][j] = f[i-1][j-1];
} else {
f[i][j] = 1 + Math.min(f[i][j-1], Math.min(f[i-1][j], f[i-1][j-1]));
}
}
}
return f[n][m];
}
}