题目链接

描述

给定一个序列,请你求出该序列的一个连续的子序列,使原串中出现的所有元素皆在该子序列中出现过至少1次。

如2 8 8 8 1 1,所求子串就是2 8 8 8 1。

  • 输入

    第一行输入一个整数T(0<T<=5)表示测试数据的组数每组测试数据的第一行是一个整数N(1<=N<=1000000),表示给定序列的长度。随后的一行有N个正整数,表示给定的序列中的所有元素。数据保证输入的整数都不会超出32位整数的范围。
  • 输出

    对于每组输入,输出包含该序列中所有元素的最短子序列的长度
  • 样例输入

    2

    5

    1 8 8 8 1

    6

    2 8 8 8 1 1
  • 样例输出

    2

    5

分析:

由于给出的数据的变化范围比较大,可能整个序列中的数为1 10000 10000 10000 1 10000这样的话我们在遍历寻找的时候肯可能出现数字比较大,没有办法进行标记。所以我们采用离散化的思想,上面的序列去重后排序,然后用他们在排序好的序列中的位置lai表示这个数,这样的话序列就变为0 1 1 1 0 1 数值的不会太大完全可以标记。

然后就是用尺取法取得所要的序列的长度,长度最短的就是要包含了所有的数字,定义一个当前序列开始的起始下标,如果到现在这个数一共有op(op为不同数字的个数)个不同的数字,那么这就是一个满足要求的序列,保存所有满足序列的长度最小值,而且在这个序列的基础上我们可以通过将序列最前面的重复数字去掉来减少数列长度。

就这样循环找,当找到op个不同数字的时候,就将起始下标往后移动,直到不同数字的个数部位op时,在往后找。

代码:

#include<stdio.h>
#include<iostream>
#include<stack>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<algorithm>
#include<set>
#include<map>
using namespace std;
int num[1000009];///num数组保存的是原始的序列
int a[1000009];///a数组保存的是去掉重复值之后的序列
int main()
{
int T,n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0; i<n; i++)
{
scanf("%d",&num[i]);
a[i]=num[i];
}
sort(a,a+n);
int op=1;
for(int i=1; i<n; i++)
{
if(a[i]!=a[i-1])
a[op++]=a[i];///op中保存的就是去掉重复值之后的序列
}
// cout<<op<<endl;
int left;
int right;
for(int i=0; i<n; i++)///离散化,原来的数值可能比较分散,利用离散化的思想吧这些数据都缩小
{
left=0;
right=op-1;
while(left<=right)
{
int mid=(left+right)/2;
if(a[mid]==num[i])
{
num[i]=mid;
break;
}
else if(a[mid]<num[i])
left=mid+1;
else
right=mid-1;
}
// printf("%d ",num[i]);
}
int sum=0;
int bj[1000009]= {0};
int le=0;
int ans=9999999;
for(int i=0; i<n; i++)///尺取法
{
if(bj[num[i]]==0) sum++;///sum表示的是当前的序列中有几个不同的数
bj[num[i]]++;
while(sum==op)///当刚好有op个不同数的时候
{
ans=min(ans,i-le+1);///当前序列中的数与之前保存的数的个数
bj[num[le]]--;///吧最前面的那个数标记释放
if(bj[num[le]]==0)
sum--;
le++;
}
}
printf("%d\n",ans);
}
return 0;
}

最新文章

  1. 解决ie6下li左浮动文字换行的问题
  2. scikit-learn包的学习资料
  3. C++迪杰斯特拉算法求最短路径
  4. [原创][LaTex]汇总博文
  5. java代码效率优化
  6. JQuery中==与===、$(&quot;#&quot;)与$(&quot;&quot;)的区别
  7. 去除inline-block之间的间隙
  8. 中国用户mac上快速安装nodejs
  9. 关于拓扑排序(topologicalsort)
  10. 【转】android UI设计的一些心得与问题解决(无效果图)
  11. jquery 的日期时间控件(年月日时分秒)
  12. 【Cocos2d-X开发学习笔记】第01期:PC开发环境的详细搭建
  13. Map &lt;STL&gt;
  14. zstuoj 4243
  15. java中数组复制的两种方式
  16. Linux mint界面过小无法安装(解决方法)
  17. [SDOI2013]森林 主席树+启发式合并
  18. stm32之CMSIS标准、库目录、GPIO
  19. mongodb第二篇文章~关于集群认证的那点事
  20. fedora23安装搜狗輸入法?

热门文章

  1. js滚动异步加载数据的思路
  2. 小程序 switch按钮
  3. 让VS2013支持 C# 6.0 语法
  4. PHP中访问控制修饰符
  5. 更新user的方法
  6. 转发---[沧海拾遗]java并发之CountDownLatch、Semaphore和CyclicBarrier
  7. 深入详解windows安全认证机制ntlm&amp;Kerberos
  8. IntelJ 快捷键
  9. [POI2005]Bank notes
  10. 同时装了Python3和Python2,怎么用pip?