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之间是否有重复元素可以有两种办法
    1. 使用一个数组,j指针移动时,自增s[a[j]],就说明这个数字已经出现过了,再出现就会自增为比1大的数,当i指针移动时,自减s[a[i]],减少s数组中a[i]项的值
    2. 使用一个容器,这里使用set哈希表,将区间内数字插入到表内,然后实时查询待插入数据出现过的次数

代码

双指针+数组

#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;
    }

}

posted @ 2023-02-19 21:53  Cheng_Mao  阅读(20)  评论(0编辑  收藏  举报