[leetcode] 583. Delete Operation for Two Strings

Given two words word1 and word2, find the minimum number of steps required to make word1 and word2 the same, where in each step you can delete one character in either string.

Example 1:

Input: "sea", "eat"
Output: 2
Explanation: You need one step to make "sea" to "ea" and another step to make "eat" to "ea".

Note:

  1. The length of given words won't exceed 500.
  2. Characters in given words can only be lower-case letters.

这道题是删除最少字符使两字符串相同,题目难度为Medium。

假设s1长度为m,s2长度为n,用steps[i][j]表示s1前i个字符和s2前j个字符至少需要steps[i][j]次删除操作才会相同。拿两个字符串最后一个字符来说,如果最后一个字符相同,这两个字符直接进行匹配,即steps[i][j] = steps[i-1][j-1],请大家自行证明;如果最后一个字符不同,则两者中至少有一个需要删除,此时steps[i][j] = min(steps[i-1][j], steps[i][j-1]) + 1。有了以上分析,采用动态规划的方法即可求出最终结果steps[m][n]。具体代码:

class Solution {
public:
    int minDistance(string word1, string word2) {
        int m = word1.size(), n = word2.size();
        vector<vector<int>> steps(m+1, vector<int>(n+1, 0));
        for(int i=0; i<m+1; ++i) steps[i][0] = i;
        for(int i=0; i<n+1; ++i) steps[0][i] = i;
        for(int i=1; i<m+1; ++i) {
            for(int j=1; j<n+1; ++j) {
                if(word1[i-1] == word2[j-1]) steps[i][j] = steps[i-1][j-1];
                else steps[i][j] = min(steps[i-1][j], steps[i][j-1]) + 1;
            }
        }
        return steps[m][n];
    }
};

按照一般动态规划题目的思路,在初步完成题目后我们要思考空间复杂度能否进行优化。这里steps是一个(m+1)*(n+1)的矩阵,steps[i][j]只和steps[i-1][j-1]、steps[i-1][j]、steps[i][j-1]三者相关,即每个位置的矩阵元素只和它左上、左边以及上面三个元素相关,因此我们可以将steps压缩为一维数组,同时用pre1和pre2分别缓存steps[i-1][j-1]和steps[i-1][j],这样通过一维数组即可完成上述动态规划的推导。具体代码:

class Solution {
public:
    int minDistance(string word1, string word2) {
        int m = word1.size(), n = word2.size();
        vector<int> steps(n+1, 0);
        
        for(int i=0; i<n+1; ++i) steps[i] = i;
        for(int i=1; i<m+1; ++i) {
            int pre1 = steps[0], pre2;
            steps[0] = i;
            for(int j=1; j<n+1; ++j) {
                pre2 = steps[j];
                if(word1[i-1] == word2[j-1]) steps[j] = pre1;
                else steps[j] = min(steps[j-1], steps[j]) + 1;
                pre1 = pre2;
            }
        }
        
        return steps[n];
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值