给定两个单词 word1 和 word2 ,返回使得 word1 和 word2 相同所需的最小步数。
每步可以删除任意一个字符串中的一个字符。
示例 1:
输入: word1 = “sea”, word2 = “eat”
输出: 2
解释: 第一步将 “sea” 变为 “ea” ,第二步将 "eat "变为 “ea”
示例 2:
输入:word1 = “leetcode”, word2 = “etco”
输出:4
提示:
1 <= word1.length, word2.length <= 500
word1 和 word2 只包含小写英文字母
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/delete-operation-for-two-strings
(1)动态规划
按照题意,每步删除任意一个字符串中的一个字符,来使删除后的 word1 和 word2 相同,最直接的方式是将它们全部删除,即都变成空串,但题目要求删除的次数尽可能少,所以此方法不通。不过换一个角度来思考,删除字符后剩下的部分就是 word1 和 word2 的最长公共子序列(LCS),而之前在LeetCode_动态规划_中等_1143.最长公共子序列这题中,我们就已经解决了如何求最长公共子序列的问题,所以删除的最小次数 = word1.length() - LCS + word2.length() - LCS。
//思路1————动态规划
public int minDistance(String word1, String word2) {
int len1 = word1.length();
int len2 = word2.length();
//求word1和word2的最长公共子序列长度
int lcs = longestCommonSubsequence(word1, word2);
return len1 - lcs + len2 - lcs;
}
//求字符串 text1 和 text2 的最长公共子序列长度
public int longestCommonSubsequence(String text1, String text2) {
int len1 = text1.length();
int len2 = text2.length();
//dp[i][j]: text1[0...i-1] 和 text2[0...j-1] 的最长公共子序列(LCS)长度
int[][] dp = new int[len1 + 1][len2 + 1];
for (int i = 1; i <= len1; i++) {
for (int j = 1; j <= len2; j++) {
if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
//text1[i-1]和text2[j-1]在LCS中
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
//text1[i-1]和text2[j-1]至少有一个不在LCS中
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp[len1][len2];
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_43004044/article/details/123396426
内容来源于网络,如有侵权,请联系作者删除!