UVA 11572 Unique Snowflakes
题意
一个长度为n的序列A,找到一个尽量长的连续子序列,并且该序列中没有相同元素
解决
- 以区间来思考这个问题,让右指针不断增加,增加到一个不能增加(冲突)的位置
- 当无法延伸右指针,也就是说A[right]在A[left,right-1]这段出现过,此时增大左指针
- 我们增加左指针的时候,可以保证A[left+1,right-1]这一段仍是可行解,所以不必减小右指针
- 判断是否存在相同元素:**利用set
双指针示范
/*
1 2 3 2 1 left right right-left ans
|| 0 0 0 0
| | 0 1 1 1
| | 0 2 2 2
| | 0 3 3 3
| | 1 3 2 3
| | 2 3 1 3
| | 2 4 2 3
| 由于没有冲突,右指针继续右移,跳出循环
*/
/*
1 2 3 2 1 left right right-left ans
|| 0 0 0 0
| | 0 1 1 1
| | 0 2 2 2
| | 0 3 3 3
| | 1 3 2 3
| | 2 3 1 3
| | 2 4 2 3
| 由于没有冲突,右指针继续右移,跳出循环
*/
int main()
{
int num[maxn] , cases, n ;
scanf("%d",&cases);
while(cases--)
{
int n;
scanf("%d",&n);
rep(i,0,n) scanf("%d",&num[i]);
long long ans=0;
set <int > myset; //用于检查是否出现重复
int left=0,right=0;
while(right<n){ //时间复杂度O(n)
while(right<n && !myset.count(num[right])) myset.insert(num[right++]);
//不冲突时,右指针一直向右移动
//右指针最后停留在第一个冲突的位置
if(right-left>ans) ans=right-left;
myset.erase(num[left++]); //左指针移动
}
cout<<ans<<endl;
}
}