题目分析
本题题意为在给定字母(区分大小写)字符串中找一个最短子区间,使得该区间内包含所有出现过的字母。
采用尺取法,l,r为区间的左右端点,记录[l,r]中各个字母出现的次数。r向右扩展, 对于每次r的扩展,尝试更新l(即l尽量向右走,当[l,r]中有多个l位置字母时l更新),然后更新ans。
代码
#include <cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<climits>
using namespace std;
map<char,int> num;
string s;
int n;
int main()
{
ios::sync_with_stdio(false);
cin>>n>>s;
int l=0,type=0,ans=n;
for(int r=0;r<s.size();r++)
{
num[s[r]]++;
while(num[s[l]]>1 && l<r)
num[s[l]]--,l++;
if(num.size()>type)
type++,ans=r-l+1;
ans=min(ans,r-l+1);
}
cout<<ans<<endl;
return 0;
}