双指针算法(最长连续不重复子序列)

(双指针算法与其说是一种算法,倒不如说是一种思想:利用两个指针维护一段序列,使其中所有的数都满足某种规则)

step1:


定义两个数组:s[N] 和 a[N]

a[N] 用来记录数组的内容

指针 i 和 j 就是用来维护数组 a 的

s[N] 用来记录在指针 j 和 i 维护的区间内,每个数出现的次数

step2:

起始时,指针 i 和 j 都在数组 a 的起点(i = 0,j = 0),此时 j 和 i 维护区间内的数就是 a[0],

所以 s[a[0]]++。(s[a[0]] = 1)

step3:

指针 i 继续移动,当移动到 s[a[i]] > 1时,说明在指针 j 和 i 维护的区间内,此时的 a[i](单单指 a[i] 所代表的数值) 出现了不止一次,那么就不符合要求(最长连续不重复子序列)

step4:

当出现 s[a[i]] > 1 的情况时,那么此时 j 和 i 维护的这段区间内,就说明出现了不止一次的 a[i](指数值) ,所以要开始移动指针 j ,直到指针 j 和 i 维护的区间内,没有多个相同的数

step5:

因为 s[N] 记录的是指针 j 和 i 维护的区间内每个数的出现次数,所以在移动 j 后,原先的 a[j](单指数值)  在指针 j 和 i 之间出现的次数就会减 1 ,所以:

s[a[j]]--;

j++;

不断移动 j ,直到 s[a[i]] = 1,说明此时指针 j 和 i 维护的区间内每个数都只出现了一次

step6:

用 res 记录满足最长连续不重复子序列的长度,直到 i = n-1,此时 res 所记录的就是数组 a 中最长连续不重复子序列的长度。

题目如下:

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

输入格式

第一行包含整数 n。

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

输出格式

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

数据范围

1≤n≤105

代码如下:

#include<iostream>
#include<cstring>

using namespace std;

const int N = 100010;

int s[N];
int a[N];
int res,n;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    
    cin >> n;
    for (int i = 0;i<n;++i)
    cin >> a[i];
    
    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;
    return 0;
}

(1)为什么移动指针 j 的结束条件是 s[a[i]] == 1?

模拟一遍什么都会了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值