算法1
(双指针) $O(n)$
我的思路跟y总不太一样。
当分别枚举到i,j出现重复时,有两种情况。
一:a[i]==a[j],此时是边界重复,由于这个区间内部的任意子序列长度都小于这个大区间的长度(i~j-1),所以不需要再重新枚举j,直接让i++,继续让j枚举寻找下一段不重复序列。
二:a[i]!=a[j],此时i~j-1之间存在与a[j]相同的数,记录这个数的位置x,让i,j从这个位置重新枚举即可。
原因:如果让j继续枚举到n,或者让i继续枚举到x,都会包含x使a[x]与a[j]相等即包含重复。
C++ 代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=1e5+10;
int n,a[N],st[N];
int l,r,res;
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i],a[i]+=1;
for(int i=1,j=1;i<=n;i++)
{ //st中存的是上一次a[j]出现的位置。
while(!st[a[j]]&&j<=n) st[a[j]]=j,j++;
res=max(res,j-i+1);
if(j==n+1) break;
if(a[j]!=a[i]) //此时说明这个区间中的以与a[j]相同的数为起点的子区间出现重复,
{
j=i=st[a[j]]+1;
memset(st,0,sizeof st);
}
}
cout<<res;
return 0;
}