版权声明:转载请标明出处哦 https://blog.csdn.net/PleasantlY1/article/details/82263767
小N现在有一个字符串S。他把这这个字符串的所有子串都挑了出来。一个S的子串T是合法的,当且仅当T中包含了所有的小写字母。小N希望知道所有的合法的S的子串中,长度最短是多少。
输入描述:
一行一个字符串S。只包含小写字母。S的长度不超过106.
输出描述:
一行一个数字,代表最短长度。数据保证存在一个合法的S的子串。
示例1
输入
ykjygvedtysvyymzfizzwkjamefxjnrnphqwnfhrnbhwjhqcgqnplodeestu
输出
49
思路:看了一眼题目,大致想了一下,没有动手写,大概是2个指针标记,一个在前标记种类,到达26种便停下,因为后面的就可以不要了。前面的指针,在遇到重复的字符时进行及时更新与前进。然后这个方法居然就是传说中的尺取法........
代码如下:
#include<set>
#include<map>
#include<list>
#include<deque>
#include<cmath>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<stdio.h>
#include<sstream>
#include<stdlib.h>
#include<string.h>
//#include<ext/rope>
#include<iostream>
#include<algorithm>
#define pi acos(-1.0)
#define INF 0x3f3f3f3f
#define per(i,a,b) for(int i=a;i<=b;++i)
#define max(a,b) a>b?a:b
#define min(a,b) a<b?a:b
#define LL long long
#define swap(a,b) {int t=a;a=b;b=t}
using namespace std;
//using namespace __gnu_cxx;
const int maxn=1e6+7;
int vis[26];
int n,s,k;
int main()
{
string s1;
cin>>s1;
s=0x3f3f3f3f;
int n=s1.size();
per(i,1,n)
{
int t=s1[i-1]-'a';
if(vis[t]==0) k++;//注意,考虑第0个元素vis更新为0的情况
vis[t]=i;
if(k==26)
{
int z=0;
per(j,0,25)
z=max(z,i-vis[j]+1);
s=min(s,z);//不能直接跳出,需要循环完每一个子串
}
}
cout<<s;
return 0;
}