双指针就是再遍历数组的时候选取两个指针,以相同方向(快慢指针),不同方向(碰撞指针)进行扫描,同时进行具体操作,有时会有两个指针遍历两个区间的情况

思考

双指针算法较为灵活,在不同的题目中会有不同的用法,主要是通过写题来理解

模板

for(int i=0,j=0;i<m;i++)
{
  while(j<n&&chick(j)) j++;
  //具体操作
}

这个只是一个很片面的模板,具体还是要看题

题目

最长连续不重复子序列open in new window 这道题是给定一个序列,求这个序列中的子序列,在序列中的位置可以不连续

那么我们首先可以先初始化一个s数组用来判断字符是否出现过,然后使用快慢指针,i指针是快指针,向前遍历的过程中,在s数组中对应位置加一,如果发现s对应位置x大于1,那么j指针开始向前遍历,直到s[x]变为一,然后和之前的结果求最大值

#include <iostream>

using namespace std;

const int N=1e5+10;

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

int main()
{
    cin>>n;
    for(int i=0;i<n;i++) cin>>m[i];
    
    for(int i=0,j=0;i<n;i++) 
    {
        s[m[i]]++;
        while(s[m[i]]>1) s[m[j++]]--;
        res=max(res,i-j+1);
        
    }
    cout<<res;
    
    return 0;
}

数组元素的目标和open in new window 这道题是给定两个递增数组和一个目标值,找出两个数组和为目标值的元素,保证一定有唯一解

这道题很明显使用双指针,由于递增,一个,从i前开始,一个j从后开始,如果大于目标值,那么j一定要--

#include <iostream>
using namespace std;

const int N=1e5+10;

int n,m,x;
long long a[N],b[N];
int main()
{
    cin>>n>>m>>x;
    for(int i=0;i<n;i++) cin>>a[i];
    for(int i=0;i<m;i++) cin>>b[i];
    for(int i=0,j=m-1;i<n;i++)
    {
        while(j>=0&&a[i]+b[j]>x) j--;
        
        if(a[i]+b[j]==x)
        {
            cout<<i<<" "<<j;
            break;
        }
    }
    
    return 0;
}
上次更新:
Contributors: YangZhang