Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit a78d23f

Browse files
✨feat: Add 583
1 parent b620969 commit a78d23f

File tree

2 files changed

+122
-0
lines changed

2 files changed

+122
-0
lines changed

‎Index/序列 DP.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
| [354. 俄罗斯套娃信封问题](https://leetcode-cn.com/problems/russian-doll-envelopes/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/russian-doll-envelopes/solution/zui-chang-shang-sheng-zi-xu-lie-bian-xin-6s8d/) | 困难 | 🤩🤩🤩🤩🤩 |
44
| [368. 最大整除子集](https://leetcode-cn.com/problems/largest-divisible-subset/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/largest-divisible-subset/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-0a3jc/) | 中等 | 🤩🤩🤩🤩 |
55
| [446. 等差数列划分 II - 子序列](https://leetcode-cn.com/problems/arithmetic-slices-ii-subsequence/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/arithmetic-slices-ii-subsequence/solution/gong-shui-san-xie-xiang-jie-ru-he-fen-xi-ykvk/) | 困难 | 🤩🤩🤩🤩🤩 |
6+
| [583. 两个字符串的删除操作](https://leetcode-cn.com/problems/delete-operation-for-two-strings/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/delete-operation-for-two-strings/solution/gong-shui-san-xie-cong-liang-chong-xu-li-wqv7/) | 中等 | 🤩🤩🤩🤩 |
67
| [673. 最长递增子序列的个数](https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/solution/gong-shui-san-xie-lis-de-fang-an-shu-wen-obuz/) | 中等 | 🤩🤩🤩🤩 |
78
| [740. 删除并获得点数](https://leetcode-cn.com/problems/delete-and-earn/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/delete-and-earn/solution/gong-shui-san-xie-zhuan-huan-wei-xu-lie-6c9t0/) | 中等 | 🤩🤩🤩🤩🤩 |
89
| [978. 最长湍流子数组](https://leetcode-cn.com/problems/longest-turbulent-subarray/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/longest-turbulent-subarray/solution/xiang-jie-dong-tai-gui-hua-ru-he-cai-dp-3spgj/) | 中等 | 🤩🤩🤩 |
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[583. 两个字符串的删除操作](https://leetcode-cn.com/problems/delete-operation-for-two-strings/solution/gong-shui-san-xie-cong-liang-chong-xu-li-wqv7/)** ,难度为 **中等**
4+
5+
Tag : 「最长公共子序列」、「序列 DP」
6+
7+
给定两个单词 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步数,每步可以删除任意一个字符串中的一个字符。
8+
9+
示例:
10+
```
11+
输入: "sea", "eat"
12+
13+
输出: 2
14+
15+
解释: 第一步将"sea"变为"ea",第二步将"eat"变为"ea"
16+
```
17+
18+
提示:
19+
* 给定单词的长度不超过500。
20+
* 给定单词中的字符只含有小写字母。
21+
22+
---
23+
24+
### 转换为 LCS 问题
25+
26+
首先,给定两字符 `s1``s2`,求经过多少次删除操作,可使得两个相等字符串。
27+
28+
该问题等价于求解两字符的「最长公共子序列」,若两者长度分别为 $n$ 和 $m,ドル而最长公共子序列长度为 $max,ドル则 $n - max + m - max$ 即为答案。
29+
30+
对「最长公共子序列(LCS)」不熟悉的同学,可以看 [(题解) 1143. 最长公共子序列](https://leetcode-cn.com/problems/longest-common-subsequence/solution/gong-shui-san-xie-zui-chang-gong-gong-zi-xq0h/)
31+
32+
**$f[i][j]$ 代表考虑 $s1$ 的前 $i$ 个字符、考虑 $s2$ 的前 $j$ 个字符(但最长公共子序列中不一定包含 $s1[i]$ 或者 $s2[j]$)时形成的「最长公共子序列(LCS)」长度。**
33+
34+
当有了「状态定义」之后,基本上「转移方程」就是呼之欲出:
35+
36+
* `s1[i]==s2[j]` : $f[i][j]=f[i-1][j-1]+1$。代表 **必然使用 $s1[i]$ 与 $s2[j]$ 时** LCS 的长度。
37+
* `s1[i]!=s2[j]` : $f[i][j]=max(f[i-1][j], f[i][j-1])$。代表 **必然不使用 $s1[i]$(但可能使用$s2[j]$)时****必然不使用 $s2[j]$(但可能使用$s1[i]$)时** LCS 的长度。
38+
39+
可以发现,上述两种讨论已经包含了「不使用 $s1[i]$ 和 $s2[j]$」、「仅使用 $s1[i]$」、「仅使用 $s2[j]$」和「使用 $s1[i]$ 和 $s2[j]$」四种情况。
40+
41+
虽然「不使用 $s1[i]$ 和 $s2[j]$」会被 $f[i - 1][j]$ 和 $f[i][j - 1]$ 重复包含,但对于求最值问题,重复比较并不想影响答案正确性。
42+
43+
因此最终的 $f[i][j]$ 为上述两种讨论中的最大值。
44+
45+
一些编码细节:
46+
47+
通常会习惯性往字符串头部追加一个空格,以减少边界判断(使下标从 1 开始,并很容易构造出可滚动的「有效值」)。但实现上,不用真的往字符串中最佳空格,只需在初始化动规值时假定存在首部空格,以及对最后的 LCS 长度进行减一操作即可。
48+
49+
代码:
50+
```Java
51+
class Solution {
52+
public int minDistance(String s1, String s2) {
53+
char[] cs1 = s1.toCharArray(), cs2 = s2.toCharArray();
54+
int n = s1.length(), m = s2.length();
55+
int[][] f = new int[n + 1][m + 1];
56+
// 假定存在哨兵空格,初始化 f[0][x] 和 f[x][0]
57+
for (int i = 0; i <= n; i++) f[i][0] = 1;
58+
for (int j = 0; j <= m; j++) f[0][j] = 1;
59+
for (int i = 1; i <= n; i++) {
60+
for (int j = 1; j <= m; j++) {
61+
f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]);
62+
if (cs1[i - 1] == cs2[j - 1]) f[i][j] = Math.max(f[i][j], f[i - 1][j - 1] + 1);
63+
}
64+
}
65+
int max = f[n][m] - 1; // 减去哨兵空格
66+
return n - max + m - max;
67+
}
68+
}
69+
```
70+
* 时间复杂度:$O(n * m)$
71+
* 空间复杂度:$O(n * m)$
72+
73+
---
74+
75+
### 序列 DP
76+
77+
上述解决方案是套用了「最长公共子序列(LCS)」进行求解,最后再根据 LCS 长度计算答案。
78+
79+
而更加契合题意的状态定义是根据「最长公共子序列(LCS)」的原始状态定义进行微调:**定义 $f[i][j]$ 代表考虑 $s1$ 的前 $i$ 个字符、考虑 $s2$ 的前 $j$ 个字符(最终字符串不一定包含 $s1[i]$ 或 $s2[j]$)时形成相同字符串的最小删除次数。**
80+
81+
同理,不失一般性的考虑 $f[i][j]$ 该如何计算:
82+
83+
* `s1[i]==s2[j]`:$f[i][j] = f[i - 1][j - 1],ドル代表可以不用必然删掉 $s1[i]$ 和 $s2[j]$ 形成相同字符串;
84+
* `s1[i]!=s2[j]`:$f[i][j] = \min(f[i - 1][j] + 1, f[i][j - 1] + 1),ドル代表至少一个删除 $s1[i]$ 和 $s2[j]$ 中的其中一个。
85+
86+
$f[i][j]$ 为上述方案中的最小值,最终答案为 $f[n][m]$。
87+
88+
代码:
89+
```Java
90+
class Solution {
91+
public int minDistance(String s1, String s2) {
92+
char[] cs1 = s1.toCharArray(), cs2 = s2.toCharArray();
93+
int n = s1.length(), m = s2.length();
94+
int[][] f = new int[n + 1][m + 1];
95+
for (int i = 0; i <= n; i++) f[i][0] = i;
96+
for (int j = 0; j <= m; j++) f[0][j] = j;
97+
for (int i = 1; i <= n; i++) {
98+
for (int j = 1; j <= m; j++) {
99+
f[i][j] = Math.min(f[i - 1][j] + 1, f[i][j - 1] + 1);
100+
if (cs1[i - 1] == cs2[j - 1]) f[i][j] = Math.min(f[i][j], f[i - 1][j - 1]);
101+
}
102+
}
103+
return f[n][m];
104+
}
105+
}
106+
```
107+
* 时间复杂度:$O(n * m)$
108+
* 空间复杂度:$O(n * m)$
109+
110+
---
111+
112+
### 最后
113+
114+
这是我们「刷穿 LeetCode」系列文章的第 `No.583` 篇,系列开始于 2021年01月01日,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
115+
116+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
117+
118+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode。
119+
120+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
121+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /