題目
給定兩個字符串,已知可以使用三種方式進行變換
- 插入一個字符
- 刪除一個字符
- 更改一個字符
請設計一個算法,找到兩個字符串之間的經歷幾次最小變換,可以字符串1轉換成字符串2
輸入描述
輸入兩個字符串,字符串的長度 <= 1000
輸出描述
最小變換次數
樣例輸入
hello
helle
樣例輸出
1
AC 代碼
import java.util.Scanner;
/**
* 典型的動態規划題目
*
* 可以用dp[i][j]來表示str1在i位置之前和str2在j位置之前字符的最小變換次數,
* 那么dp[i][j]的取值與當前位置字符的判斷有關。
*
* 遞推公式:
*
* str1[i] == str2[j]
* => dp[i][j] = dp[i-1][j-1]
*
* str1[i] != str2[j]
* => dp[i][j] = min(dp[i-1][j-1], dp[i][j-1], dp[i-1][j]) + 1
*
* 為了初始化方便,可以在str1和str2的首部添加一個哨兵字符
* 例如:
*
* # e k k o
* # 0 1 2 3 4
* h 1 1 2 3 4
* e 2 1 2 3 4
* k 3 2 1 2 3
* k 4 3 2 1 2
* o 5 4 3 2 1
*
*/
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String str1 = "#" + scanner.next();
String str2 = "#" + scanner.next();
int[][] dp = new int[str1.length()][str2.length()];
// 初始化
for (int i = 1; i < str1.length(); i++)
dp[i][0] = i;
for (int i = 1; i < str2.length(); i++)
dp[0][i] = i;
for (int i = 1; i < str1.length(); i++) {
for (int j = 1; j < str2.length(); j++) {
if (str1.charAt(i) == str2.charAt(j))
dp[i][j] = dp[i - 1][j - 1];
else {
dp[i][j] = Math.min(dp[i - 1][j - 1],
Math.min(dp[i][j - 1], dp[i - 1][j])) + 1;
}
}
}
System.out.println(dp[str1.length() - 1][str2.length() - 1]);
}
}