月月查华华的手机 (字符串匹配 枚举优化 预处理)

月月查华华的手机

题意 : q个询问 , 问其是否是主串的子序列 ;

在这里插入图片描述
在这里插入图片描述

题解 : 很显然暴力是O(n^2) 的, 所以需要优化 , 通过观察我们发现 , 子序列中字母的相对位置是不变的,所以可以维护一个数组 next[ i ][ j ], 表示第 i 个位置之后距离其最近的字母 j 所在的位置。由此数组我们便可以提高匹配效率到O(n) ;
维护方法 : 先O(n) 记录字符串中每个字符出现的位置 , 然后再从后往前O(26n) 把每个位置没更新过的字符信息更新一下 ;

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;
const int N  = 1e6+7;
char s[N];
int ne[N][30];

void init()
{
	scanf("%s",s+1);
	int n = strlen(s+1);
	for(int i=1;i<=n;i++) ne[i-1][s[i]-'a'] = i;	//i-1 位置之后距离其最近的j字符便是其本身了;
	for(int i=n-1;i>=0;i--)
		for(int j=0;j<26;j++) 
		if(!ne[i][j]) ne[i][j] = ne[i+1][j];	//倒叙传递没更新过的字符信息;
}

int main()
{
	init();
	int t;
	cin>>t;
	while(t--){
		char k[N];
		scanf("%s",k);
		int m = strlen(k),p=0,flag=1;
		for(int i=0;i<m;i++){
			p = ne[p][k[i]-'a'];	//建立指针 p=0 迭代在主串中判断某个字符是否出现在位置p后;
			if(!p){
				flag=0 ,printf("No\n");	  //一旦某个字符找不到便
				break;
			}
		}
		if(flag) printf("Yes\n");
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值