双指针算法

算法原理:

双指针算法的核心原理在于同时移动两个指针,通过控制指针的移动方式来达到特定的目的。常见的双指针算法有两种类型:

  1. 快慢指针:一个指针移动速度较快,另一个指针移动速度较慢,通常用于解决链表中的问题,比如判断链表是否有环、找到链表的中间节点等。

  2. 左右指针:两个指针分别从序列的两端开始向中间移动,通常用于解决数组或字符串中的问题,比如在有序数组中查找两数之和、反转字符串、判断回文串等。

算法步骤:

双指针算法的一般步骤如下:

  1. 初始化指针位置:根据具体问题,初始化两个指针的起始位置,通常是数组或序列的起始位置或结束位置。

  2. 移动指针:根据特定的条件,移动指针的位置,以便满足问题的要求。移动的方式可以是同时向前移动、一前一后移动、交替移动等。

  3. 判断终止条件:在移动指针的过程中,需要不断判断是否满足问题的终止条件,如果满足则停止移动。

  4. 处理问题:根据指针的位置和移动情况,解决问题并更新结果。

  5. 返回结果:返回问题的解或所需的结果。

双指针算法通常具有时间复杂度为O(n)的特点,因此在解决某些问题时具有高效的优势。

最长连续不重复子序列问题:

给定一个长度为n(1 <= n <= 100000)的整数序列,请找出最长的连续子区间,使得其中不包含重复的数,并输出该子区间的长度。

代码:

#include<iostream>

using namespace std;

const int N = 100010;
int s[N], cnt[N], n; // 定义数组和计数数组

int main()
{
    cin >> n; // 读取数组长度
    for(int i = 1; i <= n; i++) // 读取数组元素
        cin >> s[i];
    
    int max_num = 0; // 最长连续子数组的长度
    for(int i = 1, j = 1; i <= n; i++) // 使用双指针维护滑动窗口
    {
        cnt[s[i]]++; // 更新计数数组
        while(cnt[s[i]] > 1) // 当出现重复元素时,移动左指针直到没有重复元素
            cnt[s[j++]]--;
        // 更新最长连续子数组的长度
        if(max_num < i - j + 1) 
            max_num = i - j + 1;
    }
    // 输出最长连续子数组的长度
    cout << max_num;
    return 0;
}

找出两个不同数组的数,使它们的和等于目标值问题:

给定两个升序排序的有序数组A和B,以及一个目标值x,找出满足A[i]+B[j]=x的数对(i,j),其中i和j分别是A和B中的下标,且数据保证有唯一解。

代码:

#include<iostream>

using namespace std;

const int N = 100010;
int a[N], b[N], n, m, x;

int main()
{
    // 读取输入的数组长度、目标值以及数组元素
    cin >> n >> m >> x;
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    for(int i = 1; i <= m; i++)
        cin >> b[i];
    
    // 初始化两个指针分别指向数组a和数组b的起始位置和末尾位置
    int i = 1, j = m;
    // 双指针遍历数组a和数组b
    while(i <= n && j >= 1)
    {
        int t = a[i] + b[j]; // 计算当前两个数的和
        if(t == x) // 如果等于目标值x
        {
            cout << i - 1 << " " << j - 1; // 输出找到的数对的下标
            break;
        }
        else if(t > x) // 如果和大于目标值x,则向左移动数组b的指针
            j--;
        else // 如果和小于目标值x,则向右移动数组a的指针
            i++;
    }
    return 0;
}

双指针算法是一种常用的解决问题的技巧,通常用于在序列(如数组、链表)中寻找满足特定条件的子序列或子数组。其核心思想是使用两个指针在序列中移动,以达到查找、更新或维护某种关系的目的。

总结:

  1. 思想简单:双指针算法的思想简单直观,易于理解和实现。

  2. 节省空间:双指针算法通常只需要常数级别的额外空间复杂度。

  3. 时间复杂度低:双指针算法通常具有线性时间复杂度O(n),因此在解决某些问题时具有高效的优势。

  4. 适用范围广泛:双指针算法适用于解决很多问题,比如在数组中查找满足某种条件的子数组、在链表中找到环的入口等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值