LeetCode_动态规划_中等_583.两个字符串的删除操作

x33g5p2x  于2022-03-11 转载在 其他  
字(1.3k)|赞(0)|评价(0)|浏览(309)

1.题目

给定两个单词 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

2.思路

(1)动态规划
按照题意,每步删除任意一个字符串中的一个字符,来使删除后的 word1 和 word2 相同,最直接的方式是将它们全部删除,即都变成空串,但题目要求删除的次数尽可能少,所以此方法不通。不过换一个角度来思考,删除字符后剩下的部分就是 word1 和 word2 的最长公共子序列(LCS),而之前在LeetCode_动态规划_中等_1143.最长公共子序列这题中,我们就已经解决了如何求最长公共子序列的问题,所以删除的最小次数 = word1.length() - LCS + word2.length() - LCS

3.代码实现(Java)

//思路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];
}

相关文章