【AcWing】【双指针算法】799. 最长连续不重复子序列

最长连续不重复子序列

这是一道基于双指针算法的题目,但是想解这道题需要一点额外的思路,第一遍我没想出来,故在此对这道题的思路进行记录。

题目描述与输入输出

在这里插入图片描述

思路

这道题目的要求是寻找不包含重复的数的最长子序列,从题目来看可以使用双指针算法来进行求解,使用 i i i指针向后遍历,使用 j j j指针记录合法的区间起点。

问题的难题在于如何对子序列中重复的数进行判断,即判断当前子序列是否满足题目条件。

正确的解决办法是使用另一个数组 s s s来记录子序列中数字出现的次数,它的角色有点像map,但由于题目描述中提到数字的大小不会大于 1 0 5 10^5 105,因此直接使用另一个数组来存储该信息即可。

具体来说,以 1 1 1作为数组的下标起点,初始化两个指针,使i=1, j=1,在每一次迭代的过程中都使i++,并使得s[a[i]] ++,这里的 a a a数组是存储完整序列的数组,s[a[i]] ++的含义是使a[i]这个数在子序列的出现次数加一。

之后使用while循环来对 j j j指针进行移动,如果s[a[j]] > 1,则说明a[j]这个数在子序列中出现了超过两次,需要将 j j j指针右移,因为包含当前位置的子序列已经不满足“不重复”这条性质,持续地对s[a[j]]进行判断直到满足子序列的条件,停止 j j j指针的移动。

此时,使用 r e s res res来对答案进行记录,使得res = max(res, i-j+1)

最后输出 r e s res res就是最终答案。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 1e5 + 5;
int a[maxn] = {0};
int s[maxn] = {0};
int n;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n;
    for(int i=1; i<=n; i++) {
        cin >> a[i];
    }
    int res = 0;
    for(int i=1, j=1; i<=n; i++) {
        s[a[i]] ++;
        while(s[a[i]] > 1) {
            s[a[j]] --;
            j ++;
        }
        res = max(res, i - j + 1);
    }
    cout << res;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值