Day 55 583. 两个字符串的删除操作 72. 编辑距离

Day 55 583. 两个字符串的删除操作 72. 编辑距离

码农世界 2024-05-22 前端 62 次浏览 0个评论

两个字符串的删除操作

给定两个单词 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步数,每步可以删除任意一个字符串中的一个字符。

示例:

  • 输入: “sea”, “eat”
  • 输出: 2
  • 解释: 第一步将"sea"变为"ea",第二步将"eat"变为"ea"

    ​ 和上题的删除元素不太一样的点在于,两个字符串都可以进行删除操作;其他的操作都是类似的;

    ​ 1.dp数组下标及其含义

    ​ dp[i][j]: 表示word1取[0, i - 1]子序列和word2取[0, j - 1]子序列时需要最少删除dp[i][j]次可得到相同字符串;

    ​ 2.递推公式

    	if(word1[i - 1] == word2[j - 1]){
            dp[i][j] = dp[i - 1][j - 1];//相等,不需要删除
        }
    	else{
            //不等,则可以由三个方向得到
            //删除word1[i - 1]; 删除word2[j - 1]; 两个都删掉
            dp[i][j] = min(min(dp[i - 1][j] + 1, dp[i][j - 1] + 1), dp[i - 1][j - 1] + 2);
            //其实有dp[i - 1][j] = dp[i - 1][j - 1] + 1;
            //所以可以优化掉此处的dp[i - 1][j - 1] + 2;
        }
    

    ​ 3.初始化

    	//考虑定义
    	vector> dp(word1.size() + 1, vector(word2.size() + 1));
    	for(int i = 0; i <= word1.size(); i++)	dp[i][0] = i;
    	for(int j = 0; j <= word2.size(); j++)	dp[0][j] = j;
    

    ​ 4.遍历顺序

    ​ 从上到下,从左到右;

    ​ 5.打印dp

    ​ 整体代码如下:

    	int minDistance(string word1, string word2){
            vector> dp(word1.size() + 1, vector(word2.size() + 1));
       		for(int i = 0; i <= word1.size(); i++)	dp[i][0] = i;
    		for(int j = 0; j <= word2.size(); j++)	dp[0][j] = j;
            for (int i = 1; i <= word1.size(); i++) {
                for (int j = 1; j <= word2.size(); j++) {
                    if(word1[i - 1] == word2[j - 1]){
                        dp[i][j] = dp[i - 1][j - 1];
                    }
                    else{
                        dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1);
                    }
                }
            }
            return dp[word1.size()][word2.size()];
        }
    

    ​ 还有一种思路就是找到最长公共子序列,然后用两个字符串长度相加再减去二倍子序列的长度也是相同的答案;

    编辑距离

    给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。

    你可以对一个单词进行如下三种操作:

    • 插入一个字符
    • 删除一个字符
    • 替换一个字符
    • 示例 1:
    • 输入:word1 = “horse”, word2 = “ros”
    • 输出:3
    • 解释: horse -> rorse (将 ‘h’ 替换为 ‘r’) rorse -> rose (删除 ‘r’) rose -> ros (删除 ‘e’)
    • 示例 2:
    • 输入:word1 = “intention”, word2 = “execution”
    • 输出:5
    • 解释: intention -> inention (删除 ‘t’) inention -> enention (将 ‘i’ 替换为 ‘e’) enention -> exention (将 ‘n’ 替换为 ‘x’) exention -> exection (将 ‘n’ 替换为 ‘c’) exection -> execution (插入 ‘u’)

      提示:

      • 0 <= word1.length, word2.length <= 500
      • word1 和 word2 由小写英文字母组成

        ​ 前面铺垫了半天就是为了此题;

        ​ 1.dp数组下标及其含义

        ​ dp[i][j] 表示以下标i-1为结尾的字符串word1,和以下标j-1为结尾的字符串word2,最近编辑距离为dp[i][j]。

        ​ 2.递推公式

        	if(word1[i - 1] == word2[j - 1]) dp[i][j] = dp[i - 1][j - 1];//相等,不用操作
        	else{
                //不等(假设word2比word1短)
                //增:dp[i][j] = dp[i][j - 1] + 1;短到长
                //删:dp[i][j] = dp[i - 1][j] + 1;长到短
                //其实增和删的操作是相互的
                //替换:dp[i][j] = dp[i - 1][j - 1] + 1;双向替换都行
                dp[i][j] = min({dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]}) + 1;
            }
        

        ​ 3.初始化

        ​ 很显然,和上面的是一样的;

        	//考虑定义,若为空则需要删除掉另一个字符串里的所有元素
        	vector> dp(word1.size() + 1, vector(word2.size() + 1));
        	for(int i = 0; i <= word1.size(); i++)	dp[i][0] = i;
        	for(int j = 0; j <= word2.size(); j++)	dp[0][j] = j;
        

        ​ 4.遍历顺序:

        ​ 从上到下,从左到右

        ​ 5.打印dp

        ​ 整体代码如下:

        	int minDistance(string word1, string word2){
                vector> dp(word1.size() + 1, vector(word2.size() + 1));
                for(int i = 0; i <= word1.size(); i++)	dp[i][0] = i;
                for(int j = 0; j <= word2.size(); j++)	dp[0][j] = j;
                for (int i = 1; i <= word1.size(); i++) {
                	for (int j = 1; j <= word2.size(); j++) {
                        if(word1[i - 1] == word2[j - 1]){
                            dp[i][j] = dp[i - 1][j - 1];
                        }
                        else{
                			dp[i][j] = min({dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]}) + 1;
                        }
                    }
                }
                return dp[word1.size()][word2.size()];      
            }
        

转载请注明来自码农世界,本文标题:《Day 55 583. 两个字符串的删除操作 72. 编辑距离》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,62人围观)参与讨论

还没有评论,来说两句吧...

Top