Codeforces Round #765 (Div. 2) B

链接: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数组。
这种方法当给的数字过大时,数组是无法开那么大的,所以还有局限性。还是推荐我的那种做法。

猜你喜欢

转载自blog.csdn.net/qq_57109165/article/details/122489555