尺取法。
1.从第一个字符开始,向右移动右界至子串合法,用vis数组记录每个字母出现的次数,cnt表示vis记录次数为零的字母数。
2.当cnt=0时,此时每个字母都至少出现了一次,也就是说此时的长度就是一个合法子串的长度。更新ans。同时向右移动左界至子串不合法,移动过程中不断更新ans。返回第一步直至右界超过字符串长度。
3.输出ans。
代码:
#include <iostream> #include <queue> #include <set> #include <map> #include <vector> #include <stack> #include <cmath> #include <algorithm> #include <cstdio> #include <cctype> #include <functional> #include <string> #include <cstring> #include <sstream> #include <deque> using namespace std; typedef long long ll; typedef pair<int,int> P; typedef pair<P,int> Q; const int inf1=2e9+9; const ll inf2=8e18+9; const ll mol=1e9+7; const int maxn=1e5+9; const ll maxx=1e12+9; string s; int vis[26],cnt=26; int main() { cin>>s; int len=s.size(); int p1=0,p2=0,ans=inf1; while(p2<len||!cnt) { if(cnt) { if(!vis[s[p2]-'a']) cnt--; vis[s[p2]-'a']++; p2++; } if(!cnt) { ans=min(ans,p2-p1); if(vis[s[p1]-'a']==1) cnt++; vis[s[p1]-'a']--; p1++; } } cout<<ans<<endl; }