1.双指针法
class Solution {
public:
bool isSubsequence(string s, string t) {
int i=0,j=0; //两个指针,i为s的指针,j为t的指针
while(i<s.size()&&j<t.size())
{
while(t[j]!=s[i] && j<t.size()) ++j; //在t中找s里i对应的字母
if(j<t.size()) {++i;++j;}
}
if(i>=s.size())
return true;
else
return false;
}
};
2.先处理长序列,合适有多个子串要查找
class Solution {
public:
//abcada 序列t cd序列s
bool isSubsequence(string s, string t) {
vector<vector<int>> record(26); //预分配空间,可以避免vector的空间扩展浪费时间
for(int i=0;i<t.size();++i)
record[t[i]-'a'].push_back(i); //二维列表,下标为字母,一维vector为字母对应的下标列表,即该字母在t中所有出现的位置,a出现的位置为0,3,5
int last_index=-1; //记录s中上一个字母在t中出现的位置
for(int i=0;i<s.size();++i)
{
auto iter=upper_bound(record[s[i]-'a'].begin(),record[s[i]-'a'].end(),last_index); //二分法查找s中当前字母在t中的位置,要求序列是有序的,切从小到大排列,该位置应该大于上一个字母的位置last_index,因此用upper_bound
if(iter==record[s[i]-'a'].end()) return false; //满足条件的字母在t中没找到
last_index=*iter; //当前字母的位置为last_index,比如s中当前字母在t中的位置为5,则下个字母在t中的位置从6开始找
}
return true;
}
};