【LeetCode】583. 两个字符串的删除操作 Delete Operation for Two Strings(C++)


题目来源:https://leetcode-cn.com/problems/delete-operation-for-two-strings/

题目描述

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

示例:

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

提示:

给定单词的长度不超过500。
给定单词中的字符只含有小写字母。

题目大意

  • 经典动态规划题
  • 动态规划的五步骤:
    • 确定dp数组和下标含义:dp[i][j]代表以i-1结尾的字符串word1和以j-1为结尾的字符串word2
    • 确定递推公式:
      d p [ i ] [ j ] = { d p [ i − 1 ] [ j − 1 ] ( i f w o r d 1 [ i − 1 ] = = w o r d 2 [ j − 1 ] ) e l s e m i n ( m i n ( d p [ i ] [ j − 1 ] + 1 , d p [ i − 1 ] [ j ] + 1 ) , d p [ i − 1 ] [ j − 1 ] + 2 ) dp[i][j]= \left \{ \begin{array} {c}dp[i-1][j-1]{\quad}(if{\quad}word1[i-1]==word2[j-1]) \\else \\min(min(dp[i][j-1]+1,dp[i-1][j]+1),dp[i-1][j-1]+2){\quad} \end{array} \right. dp[i][j]=dp[i1][j1](ifword1[i1]==word2[j1])elsemin(min(dp[i][j1]+1,dp[i1][j]+1),dp[i1][j1]+2)
  • 继续
    • 如何定义和初始化dp数组
    • 确定遍历顺序
    • 举例推导dp数组
      在这里插入图片描述

动态规划

  • 在初始化的时候,我们需要对dp[i][0]和dp[0][j]进行遍历,因为此时是数组dp的最初状态,即对word1或word2是空串是进行初始化
  • 在确定完这五步后,思路就清晰了
class Solution {
    
    
public:
    int minDistance(string word1, string word2) {
    
    
        int len1 = word1.size(), len2 = word2.size();
        vector<vector<int>> dp(len1 + 1, vector<int>(len2 + 1));
        for (int i = 0 ; i <= len1 ; ++i)   dp[i][0] = i;
        for (int j = 0 ; j <= len2 ; ++j)   dp[0][j] = j;
        for (int i = 1 ; i <= len1 ; ++i){
    
    
            for (int j = 1 ; j <= len2 ; ++j){
    
    
                if (word1[i - 1] == word2[j - 1]){
    
    
                    dp[i][j] = dp[i - 1][j - 1];
                }
                else{
    
    
                    dp[i][j] = min(min(dp[i - 1][j] + 1, dp[i][j - 1] + 1), dp[i - 1][j - 1] + 2);
                }
            }
        }
        return dp[len1][len2];
    }
};

复杂度分析

  • 时间复杂度:O(m*n)。n为数组的长度
  • 空间复杂度:O(m*n)。n为数组的长度,维护了一个二维dp数组,二维长度为word1的长度,二维中的一维数组为word2的长度

猜你喜欢

转载自blog.csdn.net/lr_shadow/article/details/115003239