- 单点时限: 1.0sec内存限制:512 MB
给定长度为n的字符串S,定义其子字符串为S中连续的字符所组成的字符串。
若个字符串的每一个字符都独一 无二,那么我们称这样的字符串是美丽的,例如abc是美丽的,但是abb不是美丽的。请输出S的最长美丽子串的长度。
输入格式
一行一个字符串S
输出格式
一行一个整数,表示答案。
样例1
input
1
abcddbcd
output
1
4
样例2
input
1
aaaa
output
1
1
样例3
input
1
aabbcc
output
1
2
提示
样例一中最长美丽字串为abcd,长度为4
样例二中最长美丽字串为a,长度为1
样例一中最长美丽字串为ab和bc,长度为2
数据规定
- 30% :S长度 [1,100]
- 60% :S长度 [1,10000]
- 100% :S长度 [1,100000]
题解
构造一个前缀和矩阵,26行,每行代表相应字母数量前缀和。
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 100000;
int pre[26][MAXN];//前缀和矩阵,记录到此为止每个字母的数量
int main(){
string str = "";
cin >> str;
/*
26个字母,每个字母保存前缀和
*/
int len = str.size();
//初始化前缀和矩阵
for(int i = 0; i < 26; i++)
pre[i][0] = 0;
pre[str[0]-'a'][0] = 1;//初始化第一列
for(int i = 1; i < len; i++){//依次向后初始化第i列
for(int j = 0; j < 26; j++){
pre[j][i] = pre[j][i-1];
}
pre[str[i]-'a'][i] += 1;
}
// for(int i = 0; i < 26; i++){
// for(int j = 0; j < len; j++){
// cout << pre[i][j] << " ";
// }
// cout << endl;
// }
//根据前缀和矩阵,找出每个字母只能出现1次的最长子串
int res = 0;
int l = len;//子串长度
bool flag = true;//符合要求
while(res == 0){
for(int i = 0; i+l <= len; i++){
//检查26个字母是否有数量超过1的
flag = true;
if(i == 0){
for(int j = 0; j < 26; j++){
if(pre[j][i+l-1] > 1){
flag = false;
break;
}
}
}else{
for(int j = 0; j < 26; j++){
if(pre[j][i+l-1] - pre[j][i-1] > 1){//不符合要求
flag = false;
break;
}
}
}
if(flag){//符合要求
res = l;
break;
}
}
l--;
}
cout << res << endl;
return 0;
}