算法学习笔记(6)——双指针算法

双指针算法

双指针算法的核心思想就是在序列上找到这样一个性质,序列上的一个指针 \(j\) 随着另一个指针 \(i\) 的移动,是单向移动的,不会发生回退,这样就能在移动指针 \(i\) 的时候去移动指针 \(j\)。由于两个指针都最多只会把序列遍历一遍,所以时间复杂度往往是从 \(O(n^2)\) 优化到 \(O(n)\) 的,也就是双指针算法能够优化掉时间复杂度上的一个维度。

双指针算法中,两个指针可能是同向移动的(类似滑动窗口),也可能是对向移动的。

题目链接:AcWing 799. 最长连续不重复子序列

#include <iostream>

using namespace std;

const int N = 1e5 + 10;

int n;
int a[N], s[N]; // a[i]保存输入的序列,s[i]记录数字i出现的次数

int main()
{
    cin >> n;
    for (int i = 0; i < n; i ++ ) cin >> a[i];
    
    int res = 0;
    // 从前往后遍历序列,i和j是两个指针
    for (int i = 0, j = 0; i < n; i ++ ) {
        // 当前遍历到的数字的出现次数加一
        s[a[i]] ++;
        // 如果当前数字的出现次数大于一
        while (s[a[i]] > 1) {
            // 从目前维护的最长子序列的头部开始删数字,直到当前数字出现次数减为1
            s[a[j]] --;
            // 左侧指针右移
            j ++;
        }
        // 至此,j就是以i位置结尾的最长连续无重复子序列的最左位置,更新答案
        res = max(res, i - j + 1);
    }
    
    cout << res << endl;
    
    return 0;
}
posted @ 2022-12-09 22:05  S!no  阅读(46)  评论(0编辑  收藏  举报