UVA 11572 Unique Snowflakes(滑窗|双指针)

来源:互联网 发布:oppo手机网络智能优化 编辑:程序博客网 时间:2024/06/05 11:17

UVA 11572 Unique Snowflakes

题意

一个长度为n的序列A,找到一个尽量长的连续子序列,并且该序列中没有相同元素

解决

  1. 以区间来思考这个问题,让右指针不断增加,增加到一个不能增加(冲突)的位置
  2. 当无法延伸右指针,也就是说A[right]在A[left,right-1]这段出现过,此时增大左指针
  3. 我们增加左指针的时候,可以保证A[left+1,right-1]这一段仍是可行解,所以不必减小右指针
  4. 判断是否存在相同元素:**利用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;    }}