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;
}
}