给定两个单词
word1
和word2
,返回使得word1
和word2
相同所需的最小步数。每步 可以删除任意一个字符串中的一个字符。
事例:
输入: word1 = "sea", word2 = "eat" 输出: 2 解释: 第一步将 "sea" 变为 "ea" ,第二步将 "eat "变为 "ea"
思路:
使用动态规划,dp定义为:dp[i][j]表示word1从0到i - 1要跟word2从0到j - 1相同的最小删除次数。若word1[i - 1] == word2[j - 1],则此时不需要删除,dp[i][j] = dp[i - 1][j - 1]。若不相同,则需要删除其中一个,若删除word1,则dp变为i - 1与j匹配,dp[i][j] = dp[i - 1][j] + 1,若删除word2,则dp变为i与j - 1匹配,dp[i][j] = dp[i][j - 1] + 1,两者选择最小值即可。
动态规划:
dp定义及含义:dp[i][j]表示word1从0到i - 1要跟word2从0到j - 1相同的最小删除次数。
状态转移方程:if(word1[i - 1] == word2[j - 1]) dp[i][j] = dp[i - 1][j - 1]
else dp[i][j] = Math.min(dp[i - 1][j] + 1,dp[i][j - 1] + 1)
初始化:第一行和第一列表示一个字符串到空串需要删除多少次,其实就是删除另一个字符串的长度,dp[i][0] = i , dp[0][j] = j。
遍历顺序:两个for循环嵌套遍历
dp[word1.length()][word2.length()]即为答案。
代码:
public int minDistance(String word1, String word2) {
int[][] dp = new int[word1.length() + 1][word2.length() + 1];
for(int i = 1;i <= word1.length();i++){
dp[i][0] = i;
}
for(int j = 1;j <= word2.length();j++){
dp[0][j] = j;
}
for(int i = 1;i <= word1.length();i++){
for(int j = 1;j <= word2.length();j++){
if(word1.charAt(i - 1) == word2.charAt(j - 1)){
dp[i][j] = dp[i - 1][j - 1];
}else{
dp[i][j] = Math.min(dp[i - 1][j] + 1,dp[i][j - 1] + 1);
}
}
}
return dp[word1.length()][word2.length()];
}
给你两个单词
word1
和word2
, 请返回将word1
转换成word2
所使用的最少操作数 。你可以对一个单词进行如下三种操作:
- 插入一个字符
- 删除一个字符
- 替换一个字符
事例:
输入:word1 = "horse", word2 = "ros" 输出:3 解释: horse -> rorse (将 'h' 替换为 'r') rorse -> rose (删除 'r') rose -> ros (删除 'e')
思路:
与上一题类似,只是这道题多了插入和替换操作。对于两个字符串,其实存在逆向操作,如:像word1添加一个字符,也可以换为让word2删除一个字符。故不需要考虑只向word1或word2操作,和不需要考虑添加删除操作,只需要考虑删除和替换操作。
删除与上题一样,替换操作理解成:word1与word2需要替换其中一个字符,则只需要操作一次,在两者的前一个字符中选择一个替换,即dp[i][j] = dp[i - 1][j - 1] + 1。
动态规划:
dp定义及含义:dp[i][j]表示word1从0到i - 1要跟word2从0到j - 1相同需要操作多少次。
状态转移方程:if(word1[i - 1] == word[j - 1]) dp[i][j] = dp[i - 1][j - 1]
else dp[i][j] = Math.min(dp[i - 1][j] + 1,dp[i][j - 1] + 1,dp[i - 1][j - 1] + 1)。
初始化:dp[i][0] = i,dp[0][j] = j
遍历顺序:两个for循环嵌套遍历
dp[word1.length()][word2.length()]即为答案。
代码:
public int minDistance(String word1, String word2) {
int[][] dp = new int[word1.length() + 1][word2.length() + 1];
for(int i = 1;i <= word1.length();i++){
dp[i][0] = i;
}
for(int j = 1;j <= word2.length();j++){
dp[0][j] = j;
}
for(int i = 1;i <= word1.length();i++){
for(int j = 1;j <= word2.length();j++){
if(word1.charAt(i - 1) == word2.charAt(j - 1)){
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] + 1,dp[i - 1][j - 1] + 1));
}
}
}
return dp[word1.length()][word2.length()];
}
参考:代码随想录 (programmercarl.com)