给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"
是"abcde"
的一个子序列,而"aec"
不是)。
进阶:
如果有大量输入的 S,称作 S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?
致谢:
特别感谢 @pbrother 添加此问题并且创建所有测试用例。
示例 1:
输入:s = "abc", t = "ahbgdc" 输出:true
示例 2:
输入:s = "axc", t = "ahbgdc" 输出:false
提示:
0 <= s.length <= 100
0 <= t.length <= 10^4
- 两个字符串都只由小写字符组成。
解法一:双指针
class Solution {
public:
bool isSubsequence(string s, string t) {
int fast = 0; // 快指针,用于遍历字符串t
int low = 0; // 慢指针,用于遍历字符串s
while (low < s.size() && fast < t.size()) { // 慢指针未遍历完s,并且快指针未遍历完t时循环
if (s[low] == t[fast++]) // 如果当前字符相等,则将快指针往后移动一位
low++; // 慢指针往后移动一位
}
return low == s.size(); // 如果慢指针遍历完了s,则返回true,否则返回false
}
};
在这个代码只要进入while循环就会判断if语句,所以无论如何fast都会加一,而low只有在匹配成功的时候才会+1,理解这个即可做出来。
解法二:队列
class Solution {
public:
bool isSubsequence(string s, string t) {
queue<char> q; // 使用队列来存储s中的字符
for(auto& c:s){ // 遍历s中的每个字符
q.push(c); // 将字符加入队列中
}
for(auto& c:t){ // 遍历t中的每个字符
if(c == q.front()) // 如果当前字符和队列的第一个字符相等
q.pop(); // 出队,表示匹配了一个字符
}
return q.empty(); // 如果最后队列为空,则表示s是t的子序列,返回true;否则返回false
}
};
首先创造一个队列容器q,然后for循环依次将s的元素入队,再用for循环依次比对t中的元素和对头,如果相等则队头出队,如果是字串最终队列就是空,所以最后返回队列是否为空。