双指针就是再遍历数组的时候选取两个指针,以相同方向(快慢指针),不同方向(碰撞指针)进行扫描,同时进行具体操作,有时会有两个指针遍历两个区间的情况
思考
双指针算法较为灵活,在不同的题目中会有不同的用法,主要是通过写题来理解
模板
for(int i=0,j=0;i<m;i++)
{
while(j<n&&chick(j)) j++;
//具体操作
}
这个只是一个很片面的模板,具体还是要看题
题目
最长连续不重复子序列 这道题是给定一个序列,求这个序列中的子序列,在序列中的位置可以不连续
那么我们首先可以先初始化一个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;
}
数组元素的目标和 这道题是给定两个递增数组和一个目标值,找出两个数组和为目标值的元素,保证一定有唯一解
这道题很明显使用双指针,由于递增,一个,从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;
}