acwing 最长连续不重复子序列
题目
给定一个长度为 n 的整数序列,请找出最长的不包含重复的数的连续区间,输出它的长度。
输入格式
第一行包含整数 n。
第二行包含 n 个整数(均在 0 \sim 10^5 范围内),表示整数序列。
输出格式
共一行,包含一个整数,表示最长的不包含重复的数的连续区间的长度。
数据范围
1≤n≤10^5
输入样例:
5
1 2 2 3 5
输出样例:
3
题解
分析
- 如果使用朴素做法,那么就是两层for循环,此时复杂度是O(n2)
- 利用双指针,j为快指针,i为慢指针,遍历j,如果i到j范围内有重复出现,那么i++
- 检查i到j之间是否有重复元素可以有两种办法
- 使用一个数组,j指针移动时,自增
s[a[j]]
,就说明这个数字已经出现过了,再出现就会自增为比1大的数,当i指针移动时,自减s[a[i]]
,减少s数组中a[i]项的值 - 使用一个容器,这里使用set哈希表,将区间内数字插入到表内,然后实时查询待插入数据出现过的次数
- 使用一个数组,j指针移动时,自增
代码
双指针+数组
#include "iostream"
using namespace std;
const int N = 100010;
int a[N],s[N];
int main(){
int n,len=0;
cin>>n;
for(int i=0;i<n;i++)cin>>a[i];
for(int i=0,j=0;j<n;j++){
s[a[j]]++;
while (s[a[j]]>1){
s[a[i]]--;
i++;
}
len=max(len,j-i+1);
}
cout<<len;
}
双指针+哈希
#include "unordered_set"
#include "iostream"
using namespace std;
const int N = 100010;
int a[N];
bool check(int l,int r){
unordered_set<int>hash;
for(;l<=r;l++){
if(hash.count(a[l]))return false;
else hash.insert(a[l]);
}
return true;
}
int main(){
int n,len=0;
cin>>n;
for(int i=0;i<n;i++)cin>>a[i];
for(int i=0,j=0;j<n;j++){
if(check(i,j))len=max(len,j-i+1);
else i=j;
}
}