期末考试就要来了,小明打算把一本书的所有知识点都复习完,已知该书包含n页,每页包含一个知识点x,有些页的知识点有可能是重复的,小明想知道最少可以复习连续的多少页,可以把所有的知识点复习完。
第一行包含一个正整数n(1<=n<=1000000)代表该书包含多少页
第二行包含n个非负整数,代表每页包含的知识点,已知所有的知识点都在int的范围内
输出最少可以复习连续的多少页,可以把所有的知识点复习完。
输入:
5
1 8 8 8 1
输出:
2
代码(有详细注释):
#include <bits/stdc++.h> //万能头文件
using namespace std;
int n, l, r, ans, cnt;
set<unsigned int> s; //将知识点去重,统计个数
map<unsigned int, int> H;
unsigned int a[1000009];
int main () {
cin >> n; //输入n
for (int i = 1; i <= n; i++) {
cin >> a[i]; //输入
s.insert(a[i]); //推入set
}
ans = n; //初始化,最坏情况 把所有知识点看完
l = 1; r = 1; //初始化双指针
cnt = 0; //没看书之前不会任何知识点
while (1) {
//1.l保持不动,尽可能增大r
while (r <= n && cnt < s.size()) /*复习的知识点总数等于整本书就跳出*/ {
//cnt == size 跳出 表示找到了一种复习方案
//r指向的位置是将要学习的内容
H[a[r]]++;
if (H[a[r]] == 1) cnt++; //"==1"表示这个知识点第一次出现
r++;
}
//2.出口 没有符合题意的方案
if (cnt < s.size()) break; //r > n 没有元素了
//3.更新答案
ans = min (ans, r - l); //跟区间长度比较
//4.向右移动l 只会移动一个单位
H[a[l]]--;
if (H[a[l]] == 0) cnt--; //表示当前知识点已经复习到了
l++;
}
cout << ans;
return 0;
}