题目链接: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; }