链接:https://codeforces.com/contest/1625/problem/B
思路:一开始想的是双指针找相同的数,然后根据下标得到最大子串长度。后来发现会超时,于是想到了用vector+pair,来存数与对应的下标,再将数排序,那么相等的数就会相邻,然后根据下标求子串长度,再维护个最大值就行。
最大子串的长度就是,前面一个数的位置+n-后面一个数的位置。
我的代码:
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
int main()
{
int t;
cin>>t;
while(t--)
{
int n,a;
cin>>n;
int num[n];
vector<PII> q;
q.clear();
for(int i=0;i<n;i++)
cin>>num[i],q.push_back({
num[i],i+1});
sort(q.begin(),q.end());
int ans=0;
for(int i=0;i<n-1;i++)
if(q[i].first==q[i+1].first)
ans=max(ans,n-q[i+1].second+q[i].second);
if(ans==0) ans=-1;
cout<<ans<<"\n";
}
}
别人的代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
int num[N],re[N],la[N];
int main()
{
int t;
cin>>t;
while(t--)
{
int n,a;
cin>>n;
memset(num, 0, sizeof num);
memset(re, -1, sizeof re);
memset(la, 0, sizeof la);
for(int i=0;i<n;i++)
cin>>num[i];
int ans=0;
for(int i=0;i<n;i++)
{
if(re[num[i]]!=-1)
{
ans=max(ans,la[num[i]]+n-i);
la[num[i]]=i;
}
else
{
re[num[i]]++;
la[num[i]]=i;
}
}
if(ans==0) ans=-1;
cout<<ans<<endl;
}
}
这种写法中,re数组在存对应数出现的次数,la数组存对应数上次出现的位置。然后当re对应的值大于-1时说明,出现了重复的数,更新max,更新la数组。
这种方法当给的数字过大时,数组是无法开那么大的,所以还有局限性。还是推荐我的那种做法。