题目描述
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"
是"abcde"
的一个子序列,而"aec"
不是)。
进阶:
如果有大量输入的 S,称作 S1, S2, … , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?
示例 1:
1
2
| 输入:s = "abc", t = "ahbgdc"
输出:true
|
示例 2:
1
2
| 输入:s = "axc", t = "ahbgdc"
输出:false
|
提示:
0 <= s.length <= 100
0 <= t.length <= 10^4
- 两个字符串都只由小写字符组成。
题解
解法一
思路:string 的 find()
函数,当找到字符时,会返回此字符的位置,那么我继续从这个位置往下寻找,那么是不是就解决了呢?
我们对字符串 s 遍历,挨个搜索字符是否在字符串 t 里,如果在,则以此位置加一个偏移量开始继续搜索下一个字符。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| class Solution {
public:
bool isSubsequence(string s, string t) {
std::string::size_type pos{0};
for (int i = 0; i < s.size(); ++i) {
auto ipos = t.find(s[i], pos);
if (ipos == std::string::npos) {
return false;
} else {
pos = ipos + 1;
}
}
return true;
}
};
|
解法二
设置双指针 i , j 分别指向字符串 s , t 的首个字符,遍历字符串 t :
- 当 s[i] == t[j] 时,代表匹配成功,此时同时 i++ , j++ ;进而,若 i 已走过 s 尾部,代表 s 是 t 的子序列,此时应提前返回 true ;
- 当 s[i] != t[j] 时,代表匹配失败,此时仅 j++ ;
- 若遍历完字符串 t 后,字符串 s 仍未遍历完,代表 s 不是 t 的子序列,此时返回 false 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| class Solution {
public:
bool isSubsequence(string s, string t) {
if (s.size() > t.size())
return false;
for (int i = 0, j = 0; j < t.size(); j++) {
if (s[i] == t[j]) {
// 若已经遍历完 s ,则提前返回 true
if (++i == s.size())
return true;
}
}
return false;
}
};
|
预览: