import java.util.*;
/**
* NC196 编辑距离(一)
* @author d3y1
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param str1 string字符串
* @param str2 string字符串
* @return int整型
*/
public int editDistance (String str1, String str2) {
return solution1(str1, str2);
// return solution2(str1, str2);
}
/**
* 动态规划: 二维数组
*
* dp[i][j]表示使字符串str1的前i个字符与字符串str2的前j个字符相同所需要的最少操作数
*
* { dp[i-1][j-1] , str1.charAt(i-1) == str2.charAt(j-1)
* dp[i][j] = {
* { Math.min(dp[i-1][j-1]+1, Math.min(dp[i-1][j]+1, dp[i][j-1]+1)) , str1.charAt(i-1) != str2.charAt(j-1)
*
* @param str1
* @param str2
* @return
*/
private int solution1(String str1, String str2){
int n1 = str1.length();
int n2 = str2.length();
int[][] dp = new int[n1+1][n2+1];
// init 删除
for(int i=0; i<=n1; i++){
dp[i][0] = i;
}
// init 新增
for(int j=0; j<=n2; j++){
dp[0][j] = j;
}
for(int i=1; i<=n1; i++){
for(int j=1; j<=n2; j++){
// 当前字符相同
if(str1.charAt(i-1) == str2.charAt(j-1)){
dp[i][j] = dp[i-1][j-1];
}
// 当前字符不同
else{
// str1 => str2
// 修改 dp[i-1][j-1]+1
// 删除 dp[i-1][j]+1
// 新增 dp[i][j-1]+1
dp[i][j] = Math.min(dp[i-1][j-1]+1, Math.min(dp[i-1][j]+1, dp[i][j-1]+1));
}
}
}
return dp[n1][n2];
}
/**
* 动态规划: 一维数组(空间压缩)
*
* dp[j]表示编辑成字符串str2的前j个字符所需要的最少操作数
*
* { pre , str1.charAt(i-1) == str2.charAt(j-1)
* dp[j] = {
* { Math.min(pre+1, Math.min(dp[j]+1, dp[j-1]+1)) , str1.charAt(i-1) != str2.charAt(j-1)
*
* @param str1
* @param str2
* @return
*/
private int solution2(String str1, String str2){
int n1 = str1.length();
int n2 = str2.length();
int[] dp = new int[n2+1];
// init 新增
for(int j=0; j<=n2; j++){
dp[j] = j;
}
for(int i=1; i<=n1; i++){
int pre = dp[0];
// 重要
dp[0] = i;
for(int j=1; j<=n2; j++){
int tmp = dp[j];
// 当前字符相同
if(str1.charAt(i-1) == str2.charAt(j-1)){
dp[j] = pre;
}
// 当前字符不同
else{
// str1 => str2
// 修改 dp[i-1][j-1]+1 -> pre+1
// 删除 dp[i-1][j]+1 -> dp[j]+1
// 新增 dp[i][j-1]+1 -> dp[j-1]+1
dp[j] = Math.min(pre+1, Math.min(dp[j]+1, dp[j-1]+1));
}
pre = tmp;
}
}
return dp[n2];
}
}