题目链接:https://ac.nowcoder.com/acm/problem/18386
题目大意:
图片说明
思路:看完题的第一个思路:前缀和+二分。发现空间给的很小前缀和MLE。那我们换一种二分思路:保存每个字符的位置i。枚举区间左端点l。二分>=l的26个字符的最远位置r。r-l+1就是左端点为l的最小区间长度。
尺取:满足条件l++,否则r++

#include <bits/stdc++.h>
#define LL long long
using namespace std;

char s[1000005];
vector<int> v[26];
int main(){
    scanf("%s", s+1);
    int n=strlen(s+1);
    for(int i=1; i<=n; i++){
        v[s[i]-'a'].push_back(i);
    }
    for(int i=0; i<26; i++){
        sort(v[i].begin(), v[i].end());
    }
    int mi=n;
    for(int l=1; l<=n; l++){
        int ans=0;
        for(int k=0; k<26; k++){
            int pos=lower_bound(v[k].begin(), v[k].end(), l)-v[k].begin();
            if(pos<v[k].size()){
                ans=max(ans, v[k][pos]-l+1);
            }
            else{
                ans=n;


            }
        }
        mi=min(mi, ans);
    }
    printf("%d\n", mi);

    return 0;
}