package com.heu.wsq.leetcode.dp;
/**
* 72. 编辑距离
* @author wsq
* @date 2021/4/4
* 给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。
* 你可以对一个单词进行如下三种操作:
* 插入一个字符
* 删除一个字符
* 替换一个字符
*
* 示例 1:
* 输入:word1 = "horse", word2 = "ros"
* 输出:3
* 解释:
* horse -> rorse (将 'h' 替换为 'r')
* rorse -> rose (删除 'r')
* rose -> ros (删除 'e')
*
* 链接:https://leetcode-cn.com/problems/edit-distance
*/
public class MinDistance {
public int minDistance(String word1, String word2) {
int n = word1.length();
int m = word2.length();
// 状态数组, f[i][j]表示由word1的前i个字符转换为word2的前j个字符最小的编辑距离
// 最后一步,f[i][j]可以通过增加、删除和修改的方式
// 子问题,子问题涉及到
// f[i-1][j-1]:word1的前i-1个字符转为word2的前j-1个字符的最小距离(修改)
// f[i][j - 1]:word1的前i个字符转为word2的前j-1个字符的最小距离(新增一个,当前word1为i)
// f[i-1][j]:word1的前i-1个字符转为word2的前j个字符的最小距离(word1删除一个, 当前word1为i)
int[][] f = new int[n + 1][m + 1];
f[0][0] = 0;
// 根据子问题,涉及到i-1和j-1,因此需要将i=0和j = 0 进行初始化
for(int i = 1; i <= n; i++){
f[i][0] = i;
}
for(int j = 1; j <= m; j++){
f[0][j] = j;
}
// 根据状态转移矩阵求解其他状态。
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
int add = 0;
if(word1.charAt(i-1) != word2.charAt(j-1)){
add = 1;
}
f[i][j] = Math.min(f[i-1][j] + 1, Math.min(f[i-1][j-1] + add, f[i][j-1] + 1));
}
}
return f[n][m];
}
}