一、类型
分为快慢指针与对撞指针。1.快慢指针指向两段不同的内存,两指针同向移动扫描。
2.对撞指针指向同一段内存,两指针反方向移动扫描。
二、模板
for (int i = 0, j = 0; i < n; i ++ )
{
while (j < i && check(i, j)) j ++ ;//表明j的范围并检查某种性质
//每题具体逻辑
}
双指针优势:
朴素算法在第二层遍历时,会重新开始j恢复到初始位置。但双指针则不会恢复到初始位置,在满足位置的地方继续走下去。以此减少算法的复杂度。
例1
输入一个字符每个子串之间有一个空格,让你输出每一个空格后的子串。
输入 abc def hij
输出 abc
def
hij
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str;
getline(cin, str);
int n = str.size();
for(int i = 0; i < n; i++)//快慢指针
{
int j = i;
while(str[j] != ' ') j++;
for(int k = i; k < j; k++) cout<<str[k];
cout<<endl;
i = j;//每一次循环体执行完后i++,即i就到了上一次的空格(j)的下一个位置。
}
return 0;
}
例2:最长连续不重复子列
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int a[N], s[N], n;
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i ++ )scanf("%d", &a[i]);
int ans = 0;
for (int l = 0, r = 0; r < n; r ++ )//双指针
{
s[a[r]] ++ ;
while (s[a[r]] > 1)
{
s[a[l]] -- ;
l ++ ;
}
ans = max(ans, r - l + 1);
}
printf("%d\n", ans);
return 0;
}