这个题首先想到的就应该是二层循环确定L和R的位置,但是本题序列A太长了,达到10^6,二层循环10^12肯定得跪,于是有一下算法:
首先考虑起点L = 0的情况,从R= 0不断增加R,当A[R + 1]在子序列A[L-R]中出现过时,只需要不断增大L,直到A[L-R]中没有A[R + 1],再接着增加R,这样可以避免二层循环
#include<stdio.h>
#include<iostream>
#include<set>
#include<string.h>
using namespace std;
int snow[1000005];
int main()
{
int n;cin>>n;
while(n--) //有n个案例
{
int m,l = 0,r = 0,maxn = 0; //确定初始左右指针
cin>>m;
set<int> s;
memset(snow,0,sizeof(snow));
for(int i = 0;i < m;i++) //把数值放到数组snow中
cin>>snow[i];
s.insert(snow[l]);
while(1) //移动结点进行判断
{
r++;
if(maxn < r - l) maxn = r - l;
if(s.count(snow[r])) //如果存在
{
while(1)
{
s.erase(s.find(snow[l]));
l++;
if(!s.count(snow[r])) break;
}
}
s.insert(snow[r]);
if(r == m) break;
}
printf("%d\n",maxn);
}
return 0;
}