给定一个由小写字母构成的字符串 s
字符 c称为字符串 s 的 k 显性字符,当且仅当字符串 s 的所有长度不小于 k 的子串都包含字符 c
对于给定的字符串 s,请你找到一个最小的 k,使得 s 中至少存在一个 k显性字符。
输入格式
一个由小写字母构成的字符串 s
输出格式
一个整数,表示 k的最小可能值。
数据范围
前 6个测试点满足 1≤|s|≤10。
所有测试点满足 1≤|s|≤105
输入样例1:
abacaba
输出样例1:
2
输入样例2:
zzzzz
输出样例2:
1
输入样例3:
abcde
输出样例3:
3
-
本题思路:
要在字符串 s 中寻找长度不小于 k 的子串都包含同一字符,此题中字母都是小写字母,一共26个,可以用二维数组来分别记录某一字母,是第几次在s串中出现和其所在位置(如:dis[第几个字母][第几次出现]=所在位置)。这样一来我们就可以算相同字母之间间隔,这里的间隔取最大值就是该字母如果要作为字符c时k至少要为多少。再在二十六个字母各自最大间隔中取最小的即为最终的结果。此处注意:字母第一次出现距离字符串头,和字母最后一次出现距离字符串尾的长度也需要算在其中。 -
编写时遇到的问题,像dis这样的二维数组开的很大时就要注意了
函数内申请的变量,数组,是在栈(stack)中申请的一段连续的空间。栈的默认大小为2M或1M,开的比较小。
全局变量,全局数组,静态数组(static)则是开在全局区(静态区)(static)。大小为2G,所以能够开的很大。
由此可见在函数中开时不能开太大,就如同我这里定义的 dis[26][100000];如果是放在main函数中时会造成程序崩溃。
#include<bits/stdc++.h>
using namespace std;
int times[100000];
int dis[26][100000];
int main()
{
string s;
cin>>s;
int m= s.size();
int n;//表示第几个字符
for(int i=0; i<m; i++)
{
n=s[i]-'a';///表示第几个字符
times[n]++;
dis[n][times[n]]=i;///所在位置
}
int ans =2e9;
for(int i=0; i<26; i++)
{
int topdis=dis[i][1]+1;///第一次出现距离开头的距离;注意是要+1
for(int j=1; j<times[i]; j++)
{
///求相同字母每次相邻间隔出现的最大距离
topdis =max(topdis,dis[i][j+1]-dis[i][j]);
}
//cout<<m-dis[i][times[i]]<<"*"<<endl;
topdis=max(topdis,m-dis[i][times[i]]);//最后一个到结尾的长度
///不同字母的最大间隔中找最小的间隔
ans = min(ans,topdis);
}
printf("%d\n",ans);
return 0;
}