题解 | #月月查华华的手机#

月月查华华的手机

https://ac.nowcoder.com/acm/problem/23053

题意:

依次判断n个字符串是否是给定字符串的子串(不连续)

做法:

暴力做法

使用两个指针,分别从0开始比对,依次比对可能相等的字符。

但是遍历时间过长,需要加快遍历速度。

AC做法

仍然需要使用两个指针,可以考虑构造一个数组以加快父串指针的遍历速度。

可以构造一个整型数组pos[1000005][26],26依次表示26个字母

其中:pos[i][0]表示在第i个字符后,最近的字符'a'的位置;其后没有字符'a'则为-1

#include<bits/stdc++.h>
using namespace std;

void solution(){
	// 存储华华的昵称中每一个字符后面第一个指定字符的位置
	// pos[i][0]表示第i个字符后,第一个出现字符'a'的位置 
	int pos[1000005][26];
	
	char name[1000005];
	scanf("%s", name); // 华华的昵称 
	
	// last[0]存储当前位置后第一个出现字符'a'的位置 
	int last[26];
	 
	// 初始化数组 
	memset(last, -1, sizeof(last));
	memset(pos, -1, sizeof(pos));
	
	// 构造pos数组 
	for(int i = strlen(name) - 1; i >= 0; i--){
		for(int j = 0; j < 26; j++){
			if(last[j] != -1){
				pos[i][j] = last[j];
			}
		}
		last[name[i] - 'a'] = i;
	}
	
	int n, i, j;
	scanf("%d", &n);
	char person[1000005]; // 可能被搭讪的人 
	bool ans; // 结果 
	for(int a = 0; a < n; a++){
		// 对n个朋友依次检查 
		scanf("%s", person);
		i = 0;
		j = 0;	
		while(name[i] == person[j]){
			i ++;
			j ++;
		}
		ans = true;
		while(j < strlen(person)){
			if(pos[i][person[j] - 'a'] != -1){
				i = pos[i][person[j] - 'a'];
				j ++;
			}else{
				ans = false;
				break;
			}
		}
		printf(ans ? "Yes\n" : "No\n");
	}
}

int main(){
	int test = 1;
	// cin >> test;
	while(test--){
		solution();
	}
	return 0;
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务