链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
小N现在有一个字符串S。他把这这个字符串的所有子串都挑了出来。一个S的子串T是合法的,当且仅当T中包含了所有的小写字母。小N希望知道所有的合法的S的子串中,长度最短是多少。
输入描述:
一行一个字符串S。只包含小写字母。S的长度不超过106.
输出描述:
一行一个数字,代表最短长度。数据保证存在一个合法的S的子串。
示例1
输入
ykjygvedtysvyymzfizzwkjamefxjnrnphqwnfhrnbhwjhqcgqnplodeestu
输出
49
个人理解:
这种方式是:把每个字母出现的次数记录下来,eg:s [left]代表的是y,那么a [s [left] ]的意思是y出现的次数
代码:
集合(set) 做法:
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
int main()
{
set<char>st;
int i,t=0,left=0,ans=INF;
int a[200]={0};
string s;
cin>>s;
for(i=0;s[i];i++){
st.insert(s[i]);
a[s[i]]++; //统计每个字符出现的次数
while(a[s[left]]>1){ //s[left]的次数
a[s[left]]--; //次数-1,直到=1为止
left++;
}
if(st.size()==26)
ans=min(ans,i-left+1);
}
cout<<ans;
return 0;
}
map做法:
using namespace std;
#define INF 0x3f3f3f3f
int main()
{
int left=0,r=0,ans=INF,f=0,res=INF;
map<char,int>mp;
string s;
cin>>s;
while(r<s.size()){
mp[s[r++]]++;
if(mp.size()==26) //只输入了26个字母的情况
res=r-left;
while(mp[s[left]]>1){
mp[s[left]]--;
if(mp.size()==26) //更新答案
ans=min(ans,r-left-1); //因为字符串从0开始
left++;
}
}
if(ans==INF)
cout<<res;
else
cout<<ans;
return 0;
}