链接
分析
仔细读题可以发现,实际上就是找一个连续子序列,满足子序列两边的值是相等的,求这样的子序列的长度最小值。(如果中间有其它想的的数,或者是和两端相等的数,比如1,2,3,2,1或者是1,3,2, 1, 6,4,1),这种情况也可以归纳为上述情况,不再赘述。
由于数据范围为2e5,而且有多组测试,O(n^2)的算法一定不行。我们可以考虑记录每个值对应的位置,并在遍历过程中更新答案和a[i]出现的位置。如果像桶排序那样开数组的话实际上空间开销很大,所以这里应当选择用map映射。
代码
#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
const int N = 2e5 + 10;
const int INF = 0x3f3f3f3f;
int t, n;
int a[N];
map<int, int> pre;
int main() {
cin >> t;
while (t--){
cin >> n;
pre.clear();
for (int i = 1; i <= n; ++i) {
cin >> a[i];
}
if (n < 2){
printf("-1\n");
continue;
}
int ans = INF;
for (int i = 1; i <= n; ++i) {
if (!pre[a[i]]){
pre[a[i]] = i;
}
else{
ans = min(ans, i - pre[a[i]] + 1);
pre[a[i]] = i;
}
}
printf("%d\n", ans == INF? -1: ans);
}
return 0;
}