CF—1257C(Dominated Subarray)
题目
Let’s call an array t dominated by value v in the next situation.
At first, array t should have at least 2 elements. Now, let’s calculate number of occurrences of each number num in t and define it as occ(num). Then t is dominated (by v) if (and only if) occ(v)>occ(v′) for any other number v′. For example, arrays [1,2,3,4,5,2], [11,11] and [3,2,3,2,3] are dominated (by 2, 11 and 3 respectevitely) but arrays [[3]], [1,2] and [3,3,2,2,1] are not.
Small remark: since any array can be dominated only by one number, we can not specify this number and just say that array is either dominated or not.
You are given array a1,a2,…,an. Calculate its shortest dominated subarray or say that there are no such subarrays.
The subarray of a is a contiguous part of the array a, i. e. the array ai,ai+1,…,aj for some 1≤i≤j≤n.
输入
Input
The first line contains single integer T (1≤T≤1000) — the number of test cases. Each test case consists of two lines.The first line contains single integer n (1≤n≤2⋅105) — the length of the array a.
The second line contains n integers a1,a2,…,an (1≤ai≤n) — the corresponding values of the array a.
It’s guaranteed that the total length of all arrays in one test doesn’t exceed 2⋅105.
输出
Output
Print T integers — one per test case. For each test case print the only integer — the length of the shortest dominated subarray, or −1 if there are no such subarrays.
题目大意
给出T组样例,每组样例中有一个长度为n的数组,数组中元素的大小不超过n,求出数组中元素相同的两个数字之间的距离最小值,如果没有,那么输出-1.
样例输入
4
1
1
6
1 2 3 4 5 1
9
4 1 2 4 5 4 3 2 1
4
3 3 3 3
样例输出
-1
6
3
2
题目其实就是一个dp(动态规划)的思想,博主第一次被队友问到这个问题时,感觉时间2秒,挺充裕的,就随意口胡了一个中间开始查找的方法,第二天博主补题发现事情并不简单,由于博主坚信暴力出奇迹,于是努力了很久后成功TLE
于是博主开始寻找优化方式,刚好最近复习了一下动态规划,于是想到了一个遍历一次数组的O(n)想法:
于是出了下面的题解:
1.首先创建一个储存两个相同数值之间距离最小值的变量min0,并初始化为1e6(大于n的任意数字都可以),然后创建跟a一样大的数组b,用来存储跟该元素相比,前一个相同数值的下标,b的下标为a数组中的数值大小,,其实就是把a数组倒过来,a中元素大小做b的下标,元素对应的下标做b的元素大小,首先把b初始化为-1e6(这个取值也随意,小于-2e5即可)
2.开始把样例读入a数组,并进行动态规划操作:
min0=min(min0,i-b[a[i]]+1);//更新距离最小值
b[a[i]]=i;//更新b[a[i]]的数值,将b[a[i]]换成i,即最新的元素大小为a[i]的下标i
3.判断一下min0,如果min0是大于n的,那么说明min0是1e6,没找到相同的元素,输出-1;否则就说明找到相同元素的最短距离,输出min0。
这样一个相对比较快的算法就出现了(并不)
下面是代码:
#include<bits/stdc++.h>
using namespace std;
//神兽保命(滑稽)
/*
* Code is far away from bug with the animal protecting
*
*----------Dragon be here!----------/
* ┏┓ ┏┓
* ┏┛┻━━━┛┻┓
* ┃ ┃
* ┃ ━ ┃
* ┃ ┳┛ ┗┳ ┃
* ┃ ┃
* ┃ ┻ ┃
* ┃ ┃
* ┗━┓ ┏━┛
* ┃ ┃神兽保佑
* ┃ ┃代码无BUG!
* ┃ ┗━━━┓
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛
* ━━━━━━神兽出没━━━━━━
*/
int main()
{
int T,n;
int a[200005];
cin>>T;
while(T--)
{
cin>>n;
memset(a,0,sizeof(a));
int min0=1e6;
int b[200005];
memset(b,-1e6,sizeof(b));
for(int i=1;i<=n;i++)
{
cin>>a[i];
min0=min(min0,i-b[a[i]]+1);
b[a[i]]=i;
}
if(min0<2||min0>200000)
cout<<"-1"<<endl;
else
cout<<min0<<endl;
}
}
没错,我就是那个灰名小白
来源:CSDN
作者:疯狂划水的acm小白
链接:https://blog.csdn.net/weixin_44960944/article/details/103097202