赞
踩
给定一个长度为 n 的整数序列,请找出最长的不包含重复的数的连续区间,输出它的长度。
输入格式
第一行包含整数 n。
第二行包含 n 个整数(均在 0∼105范围内),表示整数序列。
输出格式
共一行,包含一个整数,表示最长的不包含重复的数的连续区间的长度
数据范围
1≤n≤105
输入样例:
- 5
- 1 2 2 3 5
输出样例:
3
- #include<iostream>
- using namespace std;
- const int N=100010;
- int n;
- int a[N],s[N];
- int main()
- {
- cin>>n;
- for(int i=0;i<n;i++) cin>>a[i];
- int res=0;
- for(int i=0,j=0;i<n;i++)
- {
- s[a[i]]++;
- while(s[a[i]]>1)
- {
- s[a[j]]--;//意思就是会到第二次出现这个数的这个位置
- j++;
- }
- res=max(res,i-j+1);
- }
- cout<<res<<endl;
- return 0;
- }
来自awing的代码
- #include<iostream>
- using namespace std;
- const int N=100010;
- int a[N],s[N];//a[N]存储n个整数
- //s[N]存储每个整数出现的次数
- /*
- Eg:5
- 1 2 2 3 5
- ↓
- s[1]=1;
- s[2]=2;
- s[3]=1;
- s[5]=1;
- 对应的就是s[a[0]]=1....s[a[1]]=2
- */
- int main()
- {
- int n;
- cin>>n;
- int maxl=1;
- for(int i=0;i<n;i++) cin>>a[i];
- for(int i=0,j=0;i<n;i++)
- {
- //i为右指针,j为左指针
- s[a[i]]++; //记录a[i]在[i,j]间出现的次数
- while(s[a[i]]>1) //当a[i]在[i,j]间出现的次数>1时,说明有元素重复了
- //左指针j开始移动,当移动到重复的元素时,重复的元素的出现次数就<1了
- //循环结束,这时[i,j]区间的元素恢复无重复元素状态
- s[a[j++]]--; //最长的不包含重复数字的连续子序列的长度
- //i-j+1就是[i,j]无重复元素区间的长度
- maxl=max(maxl,i-j+1);//比较当前[i,j]无重复元素的长度与之前的maxl值,取最大
- }
- cout<<maxl;
- return 0;
- }
可能有人对下面的代码不理解,我加以叙述。
- while(s[a[i]]>1)
- {
- s[a[j]]--;
- j++;
- }
一旦发现有某个数在s数组里面出现了两次,马上清除掉前面的记忆(也就是把前面所有的数从s数组里删掉,为了下一次求字符串的长度做准备,同时把指针j移动过来,最后的结果就是i和j移到了一起。并且i指针指的位置在s数组里还留有一个1,因为while的条件是s[a[i]]>1)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。