题目大意:一本书有N页,每页都有一个相应的知识点(知识点会重复)
现在要求你找出一个最小区间,使得这个区间覆盖了每一个知识点
解题思路:尺取法
如果不够的时候,就往右边扩
如果足够的话,就往右边缩
#include <cstdio>
#include <cstring>
#include <map>
#include <algorithm>
using namespace std;
const int N = 1000010;
const int INF = 0x3f3f3f3f;
int n, All;
int idea[N], cnt[N];
map<int,int> Map;
void init() {
Map.clear();
All = 1;
int t;
for (int i = 0; i < n; i++) {
scanf("%d", &t);
if (!Map[t])
Map[t] = All++;
idea[i] = Map[t];
}
}
void solve() {
memset(cnt, 0, sizeof(cnt));
All--;
int ans = INF, cover = 0, l = 0;
int left;
for (int i = 0; i < n; i++) {
cnt[idea[i]]++;
if (cnt[idea[i]] == 1) {
cover++;
if (cover == All) {
for (; l < i; l++)
if (--cnt[idea[l]] == 0) {
cnt[idea[l]]++;
left = idea[l];
break;
}
ans = min(ans, i - l + 1);
}
}
else if (cover == All && idea[i] == left) {
for (; l < i; l++) {
if (--cnt[idea[l]] == 0) {
cnt[idea[l]]++;
left = idea[l];
break;
}
}
ans = min(ans, i - l + 1);
}
}
printf("%d\n", ans);
}
int main() {
while (scanf("%d", &n) != EOF) {
init();
solve();
}
return 0;
}