题目描述
小N现在有一个字符串S。他把这这个字符串的所有子串都挑了出来。一个S的子串T是合法的,当且仅当T中包含了所有的小写字母。小N希望知道所有的合法的S的子串中,长度最短是多少。
输入描述:
一行一个字符串S。只包含小写字母。S的长度不超过1e6.
输出描述:
一行一个数字,代表最短长度。数据保证存在一个合法的S的子串。
题解
取尺法,定义l,r,向前枚举l,判断是否满足,如果不满足,将r向前移动,直到满足为止,
就是每次取一段,判断,然后记录最小答案。
代码
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pb push_back #define mp make_pair #define lowbit(x) x&(-x) typedef long long ll; typedef pair<int,int> pii; typedef pair<ll, ll> pll; const int N = 1e5+5; const ll mod = 1e9+7; const int INF = 0x3f3f3f3f; const double eps =1e-9; const double PI=acos(-1.0); const int dir[4][2]={-1,0,1,0,0,-1,0,1}; const int exdir[4][2]={1,1,1,-1,-1,1,-1,-1}; ll qpow(ll x,ll y){ ll ans=1,t=x; while(y>0){ if(y&1)ans*=t,ans%=mod; t*=t,t%=mod; y>>=1; } return ans%mod; } int a[26]; int check(){ for(int i=0;i<26;i++){ if(!a[i])return 0; } return 1; } void solve(){ string s;cin>>s; int l=0,r=0,ans=INF; while(l!=s.size()){ while(!check()&&r<s.size())a[s[r]-'a']++,r++; if(check())ans=min(ans,r-l); a[s[l]-'a']--,l++; } cout<<ans; } int main(){ ios::sync_with_stdio(0); cin.tie(0);cout.tie(0); //int t;cin>>t; //while(t--)solve(),cout<<'\n'; solve(); return 0; }