Solution
直观的想法是直接扫描两个字符串进行比较。这样的复杂度是 的。
然后可以发现子序列中字母的相对位置是不变的,所以可以维护一个数组 ,
表示第
个位置之后最近的字母
所在的位置。这个数组可以
处理:
,然后在倒序循环一遍即可预处理出
数组。
对于每个要判断的字符串 ,建立一个指针
,初始值为
。然后判断
的每一位是否在
中出现,并更新指针
即可。
时间复杂度: 。字符集常数较大。
Code
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=1e6+10;
int n,m,nxt[maxn][30];
char s[maxn];
int main(){
ios::sync_with_stdio(false);
cin>>s+1;
m=strlen(s+1);
for(int i=1;i<=m;i++)
nxt[i-1][s[i]-'a']=i;
for(int i=m-1;i>=0;i--)
for(int j=0;j<26;j++)
if(!nxt[i][j])
nxt[i][j]=nxt[i+1][j];
string t;
int x,y;
cin>>n;
while(n--){
cin>>t;
m=t.size();
x=y=0;
for(int i=0;i<m;i++){
x=nxt[x][t[i]-'a'];
if(!x){
y=1;
break;
}
}
if(y)
puts("No");
else
puts("Yes");
}
return 0;
} 
京公网安备 11010502036488号