72. Edit Distance
Given two strings word1
and word2
, return the minimum number of operations required to convert word1
to word2
.
You have the following three operations permitted on a word:
- Insert a character
- Delete a character
- Replace a character
Example 1:
Input: word1 = "horse", word2 = "ros" Output: 3 Explanation: horse -> rorse (replace 'h' with 'r') rorse -> rose (remove 'r') rose -> ros (remove 'e')
Example 2:
Input: word1 = "intention", word2 = "execution" Output: 5 Explanation: intention -> inention (remove 't') inention -> enention (replace 'i' with 'e') enention -> exention (replace 'n' with 'x') exention -> exection (replace 'n' with 'c') exection -> execution (insert 'u')
其实解法一的递归加记忆数组的方法也可以看作是 DP 的递归写法。这里需要维护一个二维的数组 dp,其大小为 mxn,m和n分别为 word1 和 word2 的长度。dp[i][j] 表示从 word1 的前i个字符转换到 word2 的前j个字符所需要的步骤。先给这个二维数组 dp 的第一行第一列赋值,这个很简单,因为第一行和第一列对应的总有一个字符串是空串,于是转换步骤完全是另一个字符串的长度
难点还是在于找出状态转移方程,可以举个例子来看,比如 word1 是 "bbc",word2 是 "abcd",可以得到 dp 数组如下:
Ø a b c d Ø 0 1 2 3 4 b 1 1 1 2 3 b 2 2 1 2 3 c 3 3 2 1 2
为什么第一行是1234?相当于word1是空数组,如果把空数组转成a需要1步,转成ab需要2步,转成abcd需要4步
为什么第一列是123?相当于word2是空数组,如果把word1转成空数组,把b转成空数组需要1步,把bb转成空数组需要2步,把bbc转成空数组需要3步
第二行:如果word1是b,word2是a,转换需要1步;如果word1是b,word2是ab,转换需要1步;如果word1是b,word2是abc,转换需要2步;如果word1是b,word2是abcd,转换需要3步
矩阵其他内容同理。
通过观察可以发现,当 word1[i] == word2[j] 时,dp[i][j] = dp[i - 1][j - 1],其他情况时,dp[i][j] 是其左,左上,上的三个值中的最小值加1,那么可以得到状态转移方程为:
if word1[i - 1] == word2[j - 1],dp[i][j] = dp[i - 1][j - 1] 。
else dp[i][j] = min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i][j - 1])) + 1
public static int minDistance(String word1, String word2) {
int len1 = word1.length();
int len2 = word2.length();
// len1+1, len2+1, because finally return dp[len1][len2]
int[][] dp = new int[len1 + 1][len2 + 1];
for (int i = 0; i <= len1; i++)
dp[i][0] = i;
for (int j = 0; j <= len2; j++)
dp[0][j] = j;
//iterate though, and check last char
for (int i = 1; i <= len1; i++) {
char c1 = word1.charAt(i-1);
for (int j = 1; j <= len2; j++) {
char c2 = word2.charAt(j-1);
//if last two chars equal
if (c1 == c2) {
//update dp value for +1 length
dp[i][j] = dp[i-1][j-1];
} else {
int replace = dp[i-1][j-1] + 1;
int insert = dp[i-1][j] + 1;
int delete = dp[i][j-1] + 1;
int min = Math.min(replace, insert);
min = Math.min(min,delete);
dp[i][j] = min;
}
}
}
return dp[len1][len2];
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix