AcWing学习——双指针算法

1. 概念

双指针通过两个指针以不同速度和条件来遍历某个区间,在遍历期间能够找到符合特定条件的元素或者子区间。

2. 思路

一般的双指针算法 都存在一个暴力算法 ,即O(n^2)时间复杂度 的算法,我们可以观察暴力算法的两次循环是否存在某种单调关系,如果存在可以通过双指针进行优化成为O(n)的时间复杂度

我们首先定义右指针r左指针l,每当右指针r向后移动的时候,都去判断左指针l所能达到的最左端。同时需要注意的是,r指针l指针都只会向后移动,不可能出现r指针后移,l指针左移的情况。

假设2-4范围是当前符合条件的区间,如果1-5也是符合条件的区间,那么1-4也是符合条件的区间,那么假设失败。

常见的滑动窗口问题 ,我们可以通过定义两个指针,分别表示窗口的左端和右端,通过移动左、右端下标来对窗口进行移动,需要注意的是,左端下标一定小于等于右端下标。

3. 代码模板

c++ 复制代码
for(i = 0, j = 0; i < n; i++)
{
    while(j < i && check(i, j)) j++;
    
    // 每道题的具体逻辑
    
}

4. 注意点

常见问题分类

  1. 对于一个序列,用两个指针维护一段区间
  2. 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作

5. 例题

5.1. 最长连续不重复子序列 - AcWing题库

c++ 复制代码
#include <iostream>

using namespace std;

const int N = 100010;

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

int main()
{
    cin >> n;
    for(int i = 0; i < n; i++) cin >> a[i];
    
    int 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 << endl;
    
    return 0;
}
相关推荐
人道领域36 分钟前
【LeetCode刷题日记】669.修剪二叉搜索树
开发语言·python·算法
QiLinkOS1 小时前
【从实验室到商业战场:发明专利如何重塑科技与企业的共生生态】
大数据·c语言·数据结构·c++·人工智能·单片机·算法
Irissgwe2 小时前
c++11(lambda表达式与包装器、线程库)
c++·c++11·lambda表达式·线程库·包装器·互斥量库·条件变量库
小白兔奶糖ovo2 小时前
【Leetcode】231. 2的幂
linux·算法·leetcode
xiaoxiaoxiaolll2 小时前
《Light: Science & Applications》合并BIC实现80倍阈值单模运行:超紧凑光子晶体激光器新突破
人工智能·算法·机器学习
Peter·Pan爱编程2 小时前
14. Lambda 表达式:随手可写的函数对象
c++·算法·ai编程
-To be number.wan2 小时前
算法日记 | 暴力枚举
学习·算法
s_w.h3 小时前
【 linux 】动静态库的制作
linux·运维·服务器·算法·bash
不想写代码的星星3 小时前
从分支预测角度看 C++:为什么你的热循环慢得离谱?
c++
过期动态3 小时前
【LeetCode 热题 100】接雨水
java·数据结构·算法·leetcode·职场和发展