这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战
题目
给定两个单词 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步数,每步可以删除任意一个字符串中的一个字符。
示例
输入: "sea", "eat"
输出: 2
解释: 第一步将"sea"变为"ea",第二步将"eat"变为"ea"
提示
- 给定单词的长度不超过500。
- 给定单词中的字符只含有小写字母。
解题思路
动态规划
要求公共子序列,我们可以将两个单词转换成二维列表的形式,通过动态规划的方式计算出两个单词的公共子序列长度。
因为后面的状态需要通过前面的状态来推导,在行首列首会有边界问题,因此我们需要将DP
数组行和列的长度各自+1
,以便于后面的计算。
当遇到相同元素时,取值前一位相同元素的长度再自增1
,不同元素的情况则取值左方或上方的最大长度。
得到最长公共子序列的长度之后,我们在分别用两个字符串的长度减去公共部分长度即可得到最终结果。
class Solution {
public int minDistance(String word1, String word2) {
char[] char1 = word1.toCharArray();
char[] char2 = word2.toCharArray();
int m = char1.length, n = char2.length;
// 定义DP数组,行列各 +1
int[][] dp = new int[m + 1][n + 1];
for(int i = 1; i <= m; ++i){
for(int j = 1; j <= n; ++j){
// 判断相同元素取值前一相同元素长度 +1
if(char1[i - 1] == char2[j - 1]){
dp[i][j] = dp[i - 1][j - 1] + 1;
}else{
// 不相同元素取前面最大值
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
int maxLen = dp[m][n];
// 返回结果,这里 maxLen * 2 是因为两个单词都需要减去公共部分
return m + n - maxLen * 2;
}
}
复杂度分析
- 时间复杂度:
- 空间复杂度:
最后
文章有写的不好的地方,请大佬们不吝赐教,错误是最能让人成长的,愿我与大佬间的距离逐渐缩短!
如果觉得文章对你有帮助,请 点赞、收藏、关注、评论 一键四连支持,你的支持就是我创作最大的动力!!!