【leetcode】583. 两个字符串的删除操作
距离上次更新本文已经过去了 213 天,文章部分内容可能已经过时,请注意甄别
leetcode 刷题笔记 - 583. 两个字符串的删除操作。
题目
https://leetcode.cn/problems/delete-operation-for-two-strings/
给定两个单词 word1 和 word2 ,返回使得 word1 和 word2 相同所需的最小步数。
每步 可以删除任意一个字符串中的一个字符。
plaintext
1 | 示例 1: |
提示
plaintext
1 | 1 <= word1.length, word2.length <= 500 |
思路
本题要求将两个字符串变成相同的字符串,对于给出的所有用例,肯定是能变成相同的,最大的删除操作数就是将两个字符串的所有字符都删除(即两个字符串的长度之和),此时会得到两个空字符串,空字符串自然是相等的。至于其他情况,需要求的是最少操作次数,我们需要用动态规划的思路来解题。
这道题和之前写过的 115 题:不同的子序列非常相似,在 115 题中,是用 s 的子序列去匹配 t 整个字符串,t 字符串不能改变,只能在 s 中删除字母。但本题是求两个字符串怎么通过一些操作变成相同的字符串,每一步都可以从两个字符串其中一个字符串中删除一个字符,两个字符串都能被修改。
先来走动态规划的流程吧!第一步是确定 dp 数组的含义。
dp[i][j]
:字符串 a 中下标 i-1 和字符串 b 中下标 i-1 及其之前的字符串需要至少几次操作能变成相同的字符串。- 这里也可以理解为字符串 a 中前 i 个字符组成的字符串与字符串 b 中前 j 个字符组成的字符串需要至少几次操作能变成相同的字符串。
cpp
1 | vector<vector<int>> dp(word1.size() + 1, |
然后是确定递推公式
- 情况一:
a[i-1] == b[j-1]
,此时不需要删除字符,沿用dp[i-1][j-1]
的结果就行了。 - 情况二:
a[i-1] != b[j-1]
,此时需要删除字符,有三种删除方式,取其中最小值即可:- 删除 a 中的字符,结果为
dp[i-1][j]+1
; - 删除 b 中的字符,结果为
dp[i][j-1]+1
; - 把 a 和 b 中的这俩字符都删了,结果为
dp[i-1][j-1]+2
;
- 删除 a 中的字符,结果为
dp 数组的遍历顺序,因为 dp[i][j]
很明显是依赖于 dp[i-1][j-1]
的,所以需要从左到右遍历。
再确定如何初始化 dp 数组,也分为三种情况:
i=0,j=0
的情况,两个都是空字符串,不需要做删除操作,初始化为 0;i=0
或j=0
的情况,一个是空字符串,另外一个字符串需要做的操作次数是字符串的长度次。
最终的初始化代码如下
cpp
1 | // i和j都为0的时候不需要操作,初始化为0(通过构造函数初始化) |
代码
完整代码如下,思路明白了代码还是很好写的
cpp
1 | class Solution { |
注意提交到 leetcode 时候可能会提示返回值不匹配,将函数开头的 if 里面加一个对 int
类型的强转就行了。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 慕雪的寒舍!
评论
表情图片预览
0 条评论
- 最新
- 最热
- 最早
- 作者
关闭评论
通知中心
「此时无声胜有声」
Artalk ErrorTypeError: Failed to fetch,无法获取评论列表数据
点击重新获取 | 打开控制台
点击重新获取 | 打开控制台