给定两个单词
word1
和word2
,返回使得word1
和word2
**相同所需的最小步数。每步 可以删除任意一个字符串中的一个字符。
输入: word1 = "sea", word2 = "eat"
输出: 2
解释: 第一步将 "sea" 变为 "ea" ,第二步将 "eat "变为 "ea"
这道题和昨天的不同子序列相比,就是两个字符串都可以删除。
动规五部曲:
dp[i][j]表示以i-1结尾的字符串word1,以j-1结尾的字符串word2,两个字符串想要相等,所需要删除的元素最少次数。
当word1[i-1]==word[j-1]
时 dp[i][j]=dp[i-1][j-1]
当word[i-1]≠word[j-1]
时,分为三种情况:
需要删除word1[i-1],最少操作次数为dp[i-1][j]+1
需要删除word2[j-1],最少操作次数为dp[i][j-1]+1
两个同时删除,最少操作次数为dp[i-1][j-1]+2
dp[i][j] = min({dp[i - 1][j - 1] + 2, dp[i - 1][j] + 1, dp[i][j - 1] + 1});
需要初始化dp[0][j],dp[i][0]
dp[i][0]:word2为空字符串,以i-1为结尾的字符串word1要删除多少个元素,才能和word2相同呢,很明显dp[i][0] = i。
同上,dp[0][j]=j
从前向后遍历
class Solution {
public int minDistance(String word1, String word2) {
int[][] dp=new int[word1.length()+1][word2.length()+1];
for(int i=0;i<=word1.length();i++) dp[i][0]=i;
for(int j=0;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{
int temp=Math.min(dp[i-1][j]+1,dp[i][j-1]+1);
dp[i][j]=Math.min(temp,dp[i-1][j-1]+2);
}
}
}
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')
动规五部曲:
dp[i][j]表示下标为i-1的word1,和下标j-1的word2想要相等,需要进行的最少操作数
当word1[i-1]==word[j-1]
时 dp[i][j]=dp[i-1][j-1]
(不操作)
当word[i-1]≠word[j-1]
时,分为三种情况:
需要删除word1[i-1],最少操作次数为dp[i-1][j]+1
需要删除word2[j-1],最少操作次数为dp[i][j-1]+1
两个同时删除,最少操作次数为dp[i-1][j-1]+1
dp[i][j] = min({dp[i - 1][j - 1] + 1, dp[i - 1][j] + 1, dp[i][j - 1] + 1});
dp[i][0] :以下标i-1为结尾的字符串word1,和空字符串word2,最近编辑距离为dp[i][0]。dp[i][0]=i
同上,dp[0][j]=j
从前向后遍历
class Solution {
public int minDistance(String word1, String word2) {
int[][] dp=new int[word1.length()+1][word2.length()+1];
for(int i=0;i<=word1.length();i++) dp[i][0]=i;
for(int j=0;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{
int temp=Math.min(dp[i-1][j]+1,dp[i][j-1]+1);
dp[i][j]=Math.min(temp,dp[i-1][j-1]+1);
}
}
}
return dp[word1.length()][word2.length()];
}
}
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
if (s[i - 1] == t[j - 1])
t中找到了一个字符在s中出现了dp[i][j] = dp[i - 1][j - 1] + 1;
if (s[i - 1] != t[j - 1])
t需要删除元素dp[i][j] = dp[i][j - 1];
给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数。
if (s[i - 1] == t[j - 1])
由两部分组成,分别是用s[i-1]来匹配,和不用s[i-1]匹配,dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
if (s[i - 1] != t[j - 1])
,不需要s[i-1]来匹配dp[i][j] = dp[i - 1][j];
给定两个单词 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步数,每步可以删除任意一个字符串中的一个字符。
当word1[i-1]==word[j-1]
时 dp[i][j]=dp[i-1][j-1]
当word[i-1]≠word[j-1]
时,分为三种情况:
需要删除word1[i-1],最少操作次数为dp[i-1][j]+1
需要删除word2[j-1],最少操作次数为dp[i][j-1]+1
两个同时删除,最少操作次数为dp[i-1][j-1]+2
dp[i][j] = min({dp[i - 1][j - 1] + 2, dp[i - 1][j] + 1, dp[i][j - 1] + 1});
给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。
当word1[i-1]==word[j-1]
时 dp[i][j]=dp[i-1][j-1]
(不操作)
当word[i-1]≠word[j-1]
时,分为三种情况:
需要删除word1[i-1],最少操作次数为dp[i-1][j]+1
需要删除word2[j-1],最少操作次数为dp[i][j-1]+1
两个同时删除,最少操作次数为dp[i-1][j-1]+1
dp[i][j] = min({dp[i - 1][j - 1] + 1, dp[i - 1][j] + 1, dp[i][j - 1] + 1});