Skip to content

Commit 8f2738a

Browse files
committed
algorithm: 子串, 类编辑举例
1 parent f0d88ab commit 8f2738a

File tree

5 files changed

+261
-2
lines changed

5 files changed

+261
-2
lines changed

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,9 @@ headers.h 文件所在路径: `leetcode/editor/cn/headers.h`
7676
- [x] [718-最长重复子数组](./leetcode/editor/cn/718-maximum-length-of-repeated-subarray.cpp)
7777
- [x] [1143-最长公共子序列](./leetcode/editor/cn/1143-longest-common-subsequence.cpp)
7878
- [x] [1035.不相交的线](./leetcode/editor/cn/1035-uncrossed-lines.cpp)
79-
- [x] [53-最大子序和](./leetcode/editor/cn/53-maximum-subarray.cpp)
80-
- [ ] 115-不同的子序列
79+
- [x] [53-最大子数组和](./leetcode/editor/cn/53-maximum-subarray.cpp)
80+
- [x] [392-判断子序列](./leetcode/editor/cn/392-is-subsequence.cpp)
81+
- [x] [115-不同的子序列](./leetcode/editor/cn/115-distinct-subsequences.cpp)
8182
- [ ] 583-两个字符串的删除操作
8283
- [ ] 72-编辑距离
8384
- [ ] 647-回文子串
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
//给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中 t 出现的个数。
2+
//
3+
// 题目数据保证答案符合 32 位带符号整数范围。
4+
//
5+
//
6+
//
7+
// 示例 1:
8+
//
9+
//
10+
//输入:s = "rabbbit", t = "rabbit"
11+
//输出:3
12+
//解释:
13+
//如下所示, 有 3 种可以从 s 中得到 "rabbit" 的方案。
14+
//[rabb]b[it]
15+
//[rab]b[bit]
16+
//[ra]b[bbit]
17+
// 补充: []中为加粗的部分
18+
//
19+
// 示例 2:
20+
//
21+
//
22+
//输入:s = "babgbag", t = "bag"
23+
//输出:5
24+
//解释:
25+
//如下所示, 有 5 种可以从 s 中得到 "bag" 的方案。
26+
//[ba]b[g]bag
27+
//[ba]bgba[g]
28+
//[b]abgb[ag]
29+
//ba[b]gb[ag]
30+
//babg[bag]
31+
//
32+
//
33+
//
34+
//
35+
// 提示:
36+
//
37+
//
38+
// 1 <= s.length, t.length <= 1000
39+
// s 和 t 由英文字母组成
40+
//
41+
//
42+
// Related Topics 字符串 动态规划 👍 1082 👎 0
43+
44+
45+
#include "headers.h"
46+
47+
//leetcode submit region begin(Prohibit modification and deletion)
48+
class Solution {
49+
public:
50+
// 动态规划
51+
int numDistinct(string s, string t) {
52+
vector<vector<uint64_t>> dp(s.size() + 1, vector<uint64_t>(t.size() + 1, 0));
53+
// 1. dp[i][j]: s[0:i-1], t[0:j-1] 中, t是s的子串的数量
54+
// 2. if(s[i-1] == t[j-1])
55+
// dp[i][j] = dp[i-1][j-1] + // 使用 s[i-1]来匹配
56+
// dp[i-1][j] // 不用 s[i-1] 来匹配
57+
// else
58+
// dp[i][j] = dp[i-1][j] // 没法用s[i-1]来匹配
59+
// 3. 初始化
60+
for (int i = 0; i <= s.size(); ++i) {
61+
dp[i][0] = 1;// t为空串,s 为任意字符串,都有 1 种子串
62+
}
63+
// s 为空串,t为任意字符串,则都为 0 种,与 dp 数组的初始化结合在一起
64+
for (int i = 1; i <= s.size(); ++i) {
65+
for (int j = 1; j <= t.size(); ++j) {
66+
if (s[i - 1] == t[j - 1]) {// 这里考虑到是否使用 s[i-1] 来匹配非常关键
67+
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
68+
} else {
69+
dp[i][j] = dp[i - 1][j];
70+
}
71+
}
72+
}
73+
return dp[s.size()][t.size()];
74+
}
75+
};
76+
//leetcode submit region end(Prohibit modification and deletion)
77+
78+
79+
int main() {
80+
Solution s;
81+
vector<int> arr{7, 1, 5, 3, 6, 4};
82+
auto res = s.twoSum(arr, 11);
83+
showVector(res);
84+
}
+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
//给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
2+
//
3+
// 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而
4+
//"aec"不是)。
5+
//
6+
// 进阶:
7+
//
8+
// 如果有大量输入的 S,称作 S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代
9+
//码?
10+
//
11+
// 致谢:
12+
//
13+
// 特别感谢 @pbrother 添加此问题并且创建所有测试用例。
14+
//
15+
//
16+
//
17+
// 示例 1:
18+
//
19+
//
20+
//输入:s = "abc", t = "ahbgdc"
21+
//输出:true
22+
//
23+
//
24+
// 示例 2:
25+
//
26+
//
27+
//输入:s = "axc", t = "ahbgdc"
28+
//输出:false
29+
//
30+
//
31+
//
32+
//
33+
// 提示:
34+
//
35+
//
36+
// 0 <= s.length <= 100
37+
// 0 <= t.length <= 10^4
38+
// 两个字符串都只由小写字符组成。
39+
//
40+
//
41+
// Related Topics 双指针 字符串 动态规划 👍 904 👎 0
42+
43+
44+
#include "headers.h"
45+
46+
//leetcode submit region begin(Prohibit modification and deletion)
47+
class Solution {
48+
public:
49+
// 考虑动态规划
50+
bool isSubsequence(string s, string t) {
51+
// 需要纳入编辑距离类型题目的范畴
52+
vector<vector<int>> dp(s.size() + 1, vector<int>(t.size() + 1, 0));
53+
// 1. dp[i][j]: s[0:i-1] 和 t[0:j-1] 两个子串的最大重复长度
54+
// 2. if (s[i-1] == t[j-1])
55+
// dp[i][j] = dp[i-1][j-1] + 1
56+
// else
57+
// dp[i][j] = dp[i][j-1]
58+
// 3. 初始化
59+
for (int i = 1; i <= s.size(); ++i) {
60+
for (int j = 1; j <= t.size(); ++j) {
61+
if (s[i - 1] == t[j - 1]) {
62+
dp[i][j] = dp[i - 1][j - 1] + 1;
63+
} else {// 对 t 串进行删除
64+
dp[i][j] = dp[i][j - 1];
65+
}
66+
}
67+
}
68+
return dp[s.size()][t.size()] == s.size();
69+
}
70+
71+
// 显然,双指针更加容易
72+
bool isSubsequence2(string s, string t) {
73+
int i = 0, j = 0;
74+
// 遍历 s[i] 和 t[j],
75+
while (i < s.size() && j < t.size()) {
76+
if (s[i] == t[j]) {
77+
i++;
78+
j++;
79+
} else {
80+
j++;
81+
}
82+
}
83+
return i == s.size();
84+
}
85+
};
86+
//leetcode submit region end(Prohibit modification and deletion)
87+
88+
89+
int main() {
90+
Solution s;
91+
vector<int> arr{7, 1, 5, 3, 6, 4};
92+
auto res = s.twoSum(arr, 11);
93+
showVector(res);
94+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<p>给你两个字符串 <code>s</code><strong> </strong>和 <code>t</code> ,统计并返回在 <code>s</code> 的 <strong>子序列</strong> 中 <code>t</code> 出现的个数。</p>
2+
3+
<p>题目数据保证答案符合 32 位带符号整数范围。</p>
4+
5+
<p>&nbsp;</p>
6+
7+
<p><strong>示例&nbsp;1:</strong></p>
8+
9+
<pre>
10+
<strong>输入:</strong>s = "rabbbit", t = "rabbit"<span><code>
11+
<strong>输出</strong></code></span><strong>:</strong><span><code>3
12+
</code></span><strong>解释:</strong>
13+
如下所示, 有 3 种可以从 s 中得到 <span><code>"rabbit" 的方案</code></span>。
14+
<span><code><strong><u>rabb</u></strong>b<strong><u>it</u></strong></code></span>
15+
<span><code><strong><u>ra</u></strong>b<strong><u>bbit</u></strong></code></span>
16+
<span><code><strong><u>rab</u></strong>b<strong><u>bit</u></strong></code></span></pre>
17+
18+
<p><strong>示例&nbsp;2:</strong></p>
19+
20+
<pre>
21+
<strong>输入:</strong>s = "babgbag", t = "bag"
22+
<span><code><strong>输出</strong></code></span><strong>:</strong><span><code>5
23+
</code></span><strong>解释:</strong>
24+
如下所示, 有 5 种可以从 s 中得到 <span><code>"bag" 的方案</code></span>。
25+
<span><code><strong><u>ba</u></strong>b<u><strong>g</strong></u>bag</code></span>
26+
<span><code><strong><u>ba</u></strong>bgba<strong><u>g</u></strong></code></span>
27+
<span><code><u><strong>b</strong></u>abgb<strong><u>ag</u></strong></code></span>
28+
<span><code>ba<u><strong>b</strong></u>gb<u><strong>ag</strong></u></code></span>
29+
<span><code>babg<strong><u>bag</u></strong></code></span>
30+
</pre>
31+
32+
<p>&nbsp;</p>
33+
34+
<p><strong>提示:</strong></p>
35+
36+
<ul>
37+
<li><code>1 &lt;= s.length, t.length &lt;= 1000</code></li>
38+
<li><code>s</code> 和 <code>t</code> 由英文字母组成</li>
39+
</ul>
40+
41+
<div><div>Related Topics</div><div><li>字符串</li><li>动态规划</li></div></div><br><div><li>👍 1082</li><li>👎 0</li></div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<p>给定字符串 <strong>s</strong> 和 <strong>t</strong> ,判断 <strong>s</strong> 是否为 <strong>t</strong> 的子序列。</p>
2+
3+
<p>字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,<code>"ace"</code>是<code>"abcde"</code>的一个子序列,而<code>"aec"</code>不是)。</p>
4+
5+
<p><strong>进阶:</strong></p>
6+
7+
<p>如果有大量输入的 S,称作 S1, S2, ... , Sk 其中 k &gt;= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?</p>
8+
9+
<p><strong>致谢:</strong></p>
10+
11+
<p>特别感谢<strong> </strong><a href="https://leetcode.com/pbrother/">@pbrother&nbsp;</a>添加此问题并且创建所有测试用例。</p>
12+
13+
<p>&nbsp;</p>
14+
15+
<p><strong>示例 1:</strong></p>
16+
17+
<pre>
18+
<strong>输入:</strong>s = "abc", t = "ahbgdc"
19+
<strong>输出:</strong>true
20+
</pre>
21+
22+
<p><strong>示例 2:</strong></p>
23+
24+
<pre>
25+
<strong>输入:</strong>s = "axc", t = "ahbgdc"
26+
<strong>输出:</strong>false
27+
</pre>
28+
29+
<p>&nbsp;</p>
30+
31+
<p><strong>提示:</strong></p>
32+
33+
<ul>
34+
<li><code>0 &lt;= s.length &lt;= 100</code></li>
35+
<li><code>0 &lt;= t.length &lt;= 10^4</code></li>
36+
<li>两个字符串都只由小写字符组成。</li>
37+
</ul>
38+
39+
<div><div>Related Topics</div><div><li>双指针</li><li>字符串</li><li>动态规划</li></div></div><br><div><li>👍 904</li><li>👎 0</li></div>

0 commit comments

Comments
 (0)