牛客挑战赛23-A.字符串(尺取)

版权声明:转载请标明出处哦 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;
}

猜你喜欢

转载自blog.csdn.net/PleasantlY1/article/details/82263767