392. Is Subsequence
题目大意
Given two strings s
and t
, return true
if s
is a subsequence of t
, or false
otherwise.
A subsequence of a string is a new string that is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (i.e., “ace” is a subsequence of “abcde” while “aec” is not).
中文释义
给定两个字符串 s
和 t
,如果 s
是 t
的子序列,则返回 true
,否则返回 false
。
字符串的子序列是指通过从原始字符串中删除一些(也可以不删除)字符,而不打乱剩余字符的相对位置形成的新字符串。(例如,“ace” 是 “abcde” 的一个子序列,而 “aec” 则不是)。
示例
Example 1:
Input: s = "abc"
, t = "ahbgdc"
Output: true
Example 2:
Input: s = "axc"
, t = "ahbgdc"
Output: false
限制条件
- 0 <=
s.length
<= 100 - 0 <=
t.length
<= 10^4 s
andt
consist only of lowercase English letters.
进阶问题
Follow up: Suppose there are lots of incoming s
, say s1
, s2
, …, sk
where k
>= 10^9, and you want to check one by one to see if t
has its subsequence. In this scenario, how would you change your code?
解题思路
方法
这个解决方案的目的是判断字符串 s
是否为字符串 t
的子序列。它主要使用了双指针技术来遍历两个字符串,并按照以下步骤执行:
-
初始化指针:使用两个指针
indexS
和indexT
分别指向字符串s
和t
的开始位置。 -
遍历字符串:
- 当两个指针都未达到各自字符串的末尾时,循环继续。
- 在每次循环中,比较
s[indexS]
和t[indexT]
。- 如果它们相等,意味着在
t
中找到了s
的当前字符,因此将indexS
增加 1,移动到s
的下一个字符。 - 无论是否找到匹配,都将
indexT
增加 1,移动到t
的下一个字符。
- 如果它们相等,意味着在
-
判断结果:
- 如果
indexS
等于s
的长度,意味着s
中的所有字符都按顺序在t
中找到了,因此返回true
。 - 如果循环结束时
indexS
未达到s
的末尾,意味着s
不是t
的子序列,因此返回false
。
- 如果
代码
class Solution {
public:
bool isSubsequence(string s, string t) {
int indexS = 0, indexT = 0;
while (indexS < s.size() && indexT < t.size()) {
if (s[indexS] == t[indexT++]) {
indexS++;
}
}
return indexS == s.size();
}
};
进阶解题思路
方法
该解决方案使用动态规划来预处理字符串 t
,以加速判断多个字符串 s
是否是 t
的子序列的过程。它主要分为两个步骤:
-
预处理
t
:- 创建一个二维数组
dp
,其维度为(n + 1) x 26
,其中n
是字符串t
的长度。dp[i][j]
表示从字符串t
的第i
个位置开始往后第一次出现字符j
的位置。 - 从
t
的末尾开始遍历,并为每个字符更新dp
数组。对于每个位置i
和每个可能的字符j
(a
到z
):- 如果
t[i]
等于字符j
,则dp[i][j] = i
。 - 否则,
dp[i][j] = dp[i + 1][j]
,意味着j
在t
中的下一个位置是从i + 1
开始的。
- 如果
- 创建一个二维数组
-
检查
s
是否为t
的子序列:- 为
s
设置一个指针index
,初始为 0。 - 遍历
s
的每个字符。对于每个字符c
:- 使用
dp
数组来更新index
,即index = dp[index][c - 'a']
。 - 如果
index
等于n
,表示c
字符在t
中不存在,因此s
不是t
的子序列,返回false
。 - 否则,递增
index
,继续检查下一个字符。
- 使用
- 遍历结束后,如果没有返回
false
,则表示s
是t
的子序列,返回true
。
- 为
代码
class Solution {
public:
bool isSubsequence(string s, string t) {
int n = t.size();
vector<vector<int>> dp(n + 1, vector<int>(26, n));
// 预处理 t,填充 dp 数组
for (int i = n - 1; i >= 0; i--) {
for (int j = 0; j < 26; j++) {
if (t[i] == 'a' + j)
dp[i][j] = i;
else
dp[i][j] = dp[i + 1][j];
}
}
// 检查 s 是否为 t 的子序列
int index = 0;
for (char c : s) {
index = dp[index][c - 'a'];
if (index == n) return false;
index++;
}
return true;
}
};