唯一的雪花(Unique snowflakes,UVa 11572)滑動窗口+set


輸入一個長度為n(n<=10^6)的序列A,找到一個盡量長的連續子序列AL~AR,使得該序列中沒有相同的元素。

分析:假設序列元素從0開始編號,所求連續子序列的左端點為L,右端點為R。首先考慮起點L=0的情況。可以從R=0開始不斷增加R,相當於把所求序列的右端點往右延伸。當無法延伸(即A[R+1]在子序列A[L~R]中出現過)時,只需增大L,並且繼續延伸R。既然當前的A[L~R]是可行解,L增大之后必然還是可行解,所以不必減少R,繼續增大即可。

最后考慮“判斷是否可以延伸”這個部分。比較容易想到的方法是用一個個STL的set,保存A[L~R]中元素的集合,當R增大時判斷A[R+1]是否在set中出現,而R加1時把A[R+1]插入到set中,L+1時把A[L]從set中山粗。因為set的插入刪除和查找都是O(logn)的,所以這個算法的時間復雜度為O(nlogn)。代碼如下:

#include<iostream>
#include<set>
using namespace std;

const int maxn = 1000000 + 5;
int A[maxn];

int main(){
int T,n;
cin>>T;
while(T--){
cin>>n;
for(int i = 0; i < n; i++){cin>>A[i]; }

set<int> s;
int L = 0, R = 0,ans = 0;
while(R < n){
while(R<n&&!s.count(A[R])) s.insert(A[R++]);
ans=max(ans,R-L);
s.erase(A[L++]);
}
cout<<ans<<endl;
}
return 0;
}

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com