解法,two pointers横着扫一遍,双指针选取子串,int型vis数组标记字串中字符出现的字符种类。
CODE
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
char s[N];
int main(void)
{
int n;
scanf("%d %s",&n,s);
int vis[300] = {0};
int len = strlen(s);
int num = 0;
for(int i = 0;i < len;i++){ ///标记有多少种类
if(!vis[s[i]])
num++;
vis[s[i]]++;
}
memset(vis,0,sizeof vis);
int ans = N;
int tmp = 0;
for(int l = 0,r = 0;l < n;l++){
while(r < n && tmp < num){ ///左右指针中间字符种类的数量
if(!vis[s[r]]){
tmp++;
}
vis[s[r++]]++;
}
if(tmp == num)
ans = min(r-l,ans); ///左右指针中间种类数达到num记录答案最小值
vis[s[l]]--; ///取消左指针的标记
if(vis[s[l]] == 0) tmp--; ///左指针标记的字符出现次数为0,tmp--
}
printf("%d",ans);
return 0;
}