记录--有惊无险
问题描述
解决了巨石迷阵,小
L
L
L长舒一口气。他坐在一棵繁茂的树下刚打开地图,突然,四周轰隆隆又一阵巨响,面前又出现了许多巨石。
情报有误!情报有误!!
根据搜集来的情报,这里不应该再次出现这么多巨石!
小
L
L
L赶忙起身,屏气凝神,重新专注起来…
有一个长度为
n
n
n的字符串,找到一个区间
[
l
,
r
]
[l,r]
[l,r],使得处于区间
[
l
,
r
]
[l,r]
[l,r]的石块上的字母,26个大写字母都至少出现一次。输出这个区间长度的最小值。
数据保证有解
输入格式
第-行一个整数
n
,
n
<
2
×
1
0
5
n,n<2\times10^5
n,n<2×105
第二行,一个长度为
n
n
n的字符串
输出格式
一行,一个数,代表最短长度
样例输入
30
30
AABBCDEFGHIJKLMNOPQRSTUVWXYZZZ
样例输出
27
思路
做一个窗口滑动函数,保证窗口的距离在符合条件的同时最小。
完整代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//做一个窗口滑动函数
int func(const string& s) {
unordered_map<char, int> charCount;
int tot = 26;
int l = 0, minlen = 999999999;
int count = 0;
//保持[l, r]区间中出现26个字母时,尽量保持最小距离(l增大)
for (int r = 0; r < s.size(); r++) {
if (charCount[s[r]] == 0) {
count++;
}
charCount[s[r]]++;
while (count == tot) {
minlen = min(minlen, r - l + 1);
charCount[s[l]]--;
if (charCount[s[l]] == 0) {
count--;
}
l++;
}
}
return minlen;
}
int main() {
int n = 0;
cin >> n;
string s;
cin >> s;
int ans = func(s);
cout << ans << endl;
return 0;
}