zoukankan      html  css  js  c++  java
  • UVA11527Unique Snowflakes(滑动窗口 + set判重 | | map)

    题意:输入长度为n的序列a,找到一个尽量长的连续子序列a[l] - a[r],使该序列中没有相同的元素

    紫薯P239

    序列元素从0开始编号,l 和 r 分别表示子序列左右端点,初始化为0,固定 l,判断加入 a[r] 是否重复,如不重复,加入,同时r++,若重复,l++,然后再判断加入a[r]是否重复..

    时间复杂度:r从0到n,判重由set来处理lgn,总O(nlgn)

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstdio>
     4 #include <set>
     5 using namespace std;
     6 int main()
     7 {
     8     int t, n;
     9     scanf("%d", &t);
    10     while (t--)
    11     {
    12         scanf("%d", &n);
    13         int *a = new int[n]; //动态分配
    14         for (int i = 0; i < n; i++)
    15             scanf("%d", &a[i]);
    16         int l, r, maxL;
    17         maxL = l = r = 0;
    18         set<int> s;
    19         while (r < n)
    20         {
    21             while (r < n && s.count(a[r]) == 0)  //判断加入r是否重复
    22             {
    23                 s.insert(a[r]);
    24                 r++;
    25             }
    26             maxL = max(maxL, r - l);
    27             s.erase(a[l]); // 将l处的移除set
    28             l++;
    29         }
    30         printf("%d
    ", maxL);
    31     }
    32     return 0;
    33 }
    View Code

     用map来求

    last[i] = x表示第i各位置的数上一次出现是在第x位置,故对于 r 位置的数来说,如果他上次出现在 l 位置之前,则 r 是可以扩展的,否则 l++;

    记录每个位置上一次出现的位置可以用map来映射。

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <set>
    #include <map>
    using namespace std;
    int main()
    {
        int t, n;
        scanf("%d", &t);
        while (t--)
        {
            scanf("%d", &n);
            int *a = new int[n];
            int *last = new int[n];
            map<int, int> m;
            for (int i = 0; i < n; i++)
            {
                scanf("%d", &a[i]);
                if ( m.count(a[i]) == 0 )
                {
                    last[i] = -1; // 如果上次没有出现,设为-1
                }
                else
                {
                    last[i] = m[ a[i] ]; // 如果上次出现,找到上次出现的位置
                }
                m[ a[i] ] = i;  // 这次出现的位置
            }
            int l, r, maxL;
            l = r = maxL = 0;
            while (r < n)
            {
                while (r < n && last[r] < l) // 一定是last[r] < l时,r才加一
                    r++;
                maxL = max(maxL, r - l);
                l++;
            }
            printf("%d
    ", maxL);
            delete[] a;
            delete[] last;
        }
        return 0;
    }
    

      

  • 相关阅读:
    Suricata 1.3.3 发布,入侵检测系统
    Blue Mind 1.0 正式版发布,消息和协作平台
    Ceylon M4 和 Ceylon IDE M4 发布
    微软正式开放 Windows Phone 8 SDK 下载
    SchemaCrawler 9.3 发布
    ASP.NET防伪令牌与JSON有效载荷
    WinRT控件:图表、图示、地图和其他
    dhtmlxSpreadsheet 2.0 发布,表格生成工具
    Funcito 1.2.0 发布,Java 函数式编程库
    Rabel 1.3.9 发布,让论坛回归交流本质
  • 原文地址:https://www.cnblogs.com/zhaopAC/p/6275495.html
Copyright © 2011-2022 走看看