当前位置:   article > 正文

10. 最长连续不重复子序列 (C++)_最长不重复子序列

最长不重复子序列

给定一个长度为 n 的整数序列,请找出最长的不包含重复的数的连续区间,输出它的长度。

输入格式

第一行包含整数 n。

第二行包含 n 个整数(均在 0∼105范围内),表示整数序列。

输出格式

共一行,包含一个整数,表示最长的不包含重复的数的连续区间的长度

数据范围

1≤n≤105

输入样例:

  1. 5
  2. 1 2 2 3 5

输出样例:

3
  1. #include<iostream>
  2. using namespace std;
  3. const int N=100010;
  4. int n;
  5. int a[N],s[N];
  6. int main()
  7. {
  8. cin>>n;
  9. for(int i=0;i<n;i++) cin>>a[i];
  10. int res=0;
  11. for(int i=0,j=0;i<n;i++)
  12. {
  13. s[a[i]]++;
  14. while(s[a[i]]>1)
  15. {
  16. s[a[j]]--;//意思就是会到第二次出现这个数的这个位置
  17. j++;
  18. }
  19. res=max(res,i-j+1);
  20. }
  21. cout<<res<<endl;
  22. return 0;
  23. }

来自awing的代码

  1. #include<iostream>
  2. using namespace std;
  3. const int N=100010;
  4. int a[N],s[N];//a[N]存储n个整数
  5. //s[N]存储每个整数出现的次数
  6. /*
  7. Eg:5
  8. 1 2 2 3 5
  9. s[1]=1;
  10. s[2]=2;
  11. s[3]=1;
  12. s[5]=1;
  13. 对应的就是s[a[0]]=1....s[a[1]]=2
  14. */
  15. int main()
  16. {
  17. int n;
  18. cin>>n;
  19. int maxl=1;
  20. for(int i=0;i<n;i++) cin>>a[i];
  21. for(int i=0,j=0;i<n;i++)
  22. {
  23. //i为右指针,j为左指针
  24. s[a[i]]++; //记录a[i]在[i,j]间出现的次数
  25. while(s[a[i]]>1) //当a[i]在[i,j]间出现的次数>1时,说明有元素重复了
  26. //左指针j开始移动,当移动到重复的元素时,重复的元素的出现次数就<1
  27. //循环结束,这时[i,j]区间的元素恢复无重复元素状态
  28. s[a[j++]]--; //最长的不包含重复数字的连续子序列的长度
  29. //i-j+1就是[i,j]无重复元素区间的长度
  30. maxl=max(maxl,i-j+1);//比较当前[i,j]无重复元素的长度与之前的maxl值,取最大
  31. }
  32. cout<<maxl;
  33. return 0;
  34. }

可能有人对下面的代码不理解,我加以叙述。

  1. while(s[a[i]]>1)
  2.         {
  3.             s[a[j]]--;
  4.             j++;
  5.         }


一旦发现有某个数在s数组里面出现了两次,马上清除掉前面的记忆(也就是把前面所有的数从s数组里删掉,为了下一次求字符串的长度做准备,同时把指针j移动过来,最后的结果就是i和j移到了一起。并且i指针指的位置在s数组里还留有一个1,因为while的条件是s[a[i]]>1)

对于数据 1 2 3 2 5 列图来表示:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/521553
推荐阅读
相关标签
  

闽ICP备14008679号