LeetCode392_判断子序列
- [标签:#双指针 #字符串 #动态规划](#双指针 #字符串 #动态规划)
-
- [Ⅰ. 题目](#Ⅰ. 题目)
- [Ⅱ. 示例](#Ⅱ. 示例)
- [0. 个人方法](#0. 个人方法)
- 官方题解一:双指针
- 官方题解二:动态规划
标签:#双指针 #字符串 #动态规划
Ⅰ. 题目
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。
- 进阶:
如果有大量输入的 S,称作 S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?
Ⅱ. 示例
· 示例 1:
输入:s = "abc", t = "ahbgdc"
输出:true
· 示例 2:
输入:s = "axc", t = "ahbgdc"
输出:false
0. 个人方法
遍历字符串 t,逐个和 s 字符串对比,如果相同就让cnt++(我的代码里写的是 position),不同就继续遍历字符串 t,如果 cnt == s.length(),那么就说明字符串 t 中有字符串 s 这个子序列
cpp
class Solution {
public:
bool isSubsequence(string s, string t) {
if (t.length() < s.length())
return false;
if (t.length() == 0 && s.length() == 0)
return true;
int position = 0;
for (int i=0; i<t.length(); ++i)
{
if (t[i] == s[position])
{
position++;
}
if (position == s.length())
{
return true;
}
}
return false;
}
};
官方题解一:双指针
大致思路与个人方法相同
cpp
class Solution {
public:
bool isSubsequence(string s, string t) {
int n = s.length(), m = t.length();
int i = 0, j = 0;
while (i < n && j < m) {
if (s[i] == t[j]) {
i++;
}
j++;
}
return i == n;
}
};
官方题解二:动态规划
(如果需要多次查询 s 是否是 t 的子序列,DP方法更高效)
考虑到前面双指针的做法,我们注意到我们有大量的时间用于在 t 中找到下一个匹配字符。
因此,我们可以考虑对 t 进行预处理,记录从当前位置起,往后每一个字符第一次出现的位置。
cpp
class Solution {
public:
bool isSubsequence(string s, string t) {
int n = s.size(), m = t.size();
// DP 表:f[i][j] 表示 t 从位置 i 开始,字符 j 第一次出现的位置
vector<vector<int>> f(m + 1, vector<int>(26, 0));
// 初始化边界:如果 t 的末尾之后的位置,所有字符都不可达(设为 m)
for (int j = 0; j < 26; j++) {
f[m][j] = m;
}
// 填充 DP 表
for (int i = m - 1; i >= 0; i--) {
for (int j = 0; j < 26; j++) {
if (t[i] == j + 'a') // 当前字符匹配
f[i][j] = i;
else // 否则继承 i+1 的结果
f[i][j] = f[i + 1][j];
}
}
// 遍历 s,检查是否能在 t 中找到匹配的字符
int add = 0; // 当前在 t 中的查找起始位置
for (int i = 0; i < n; i++) {
if (f[add][s[i] - 'a'] == m) { // 字符 s[i] 在 t 中不存在
return false;
}
add = f[add][s[i] - 'a'] + 1; // 跳到匹配位置的下一个位置
}
return true; // 所有字符都匹配成功
}
};
-
示例1:
-
输入:s = "abc", t = "ahbgdc"
-
预处理 t 后,f 会记录每个字符的位置。
-
匹配 s:
-
'a' 在 t 的位置 0 → add = 1
-
'b' 在 t 的位置 2 → add = 3
-
'c' 在 t 的位置 5 → 匹配成功
-
-
-
输出:true
-
-
示例2:
-
输入:s = "axc", t = "ahbgdc"
-
'a' 匹配 t[0] → add = 1
-
'x' 在 t 中不存在 → 返回 false
-
-