双指针
双指针算法思想
实用i,j两个变量,不会退的扫描一个数组
常规写法
for(int i=0,j=0,i<n;i++){
while(j<i&&check(i,j)) j++;
}
这是i,j分别两端的写法
int i=0,j=n-1;
while(i<j){
if(check(i,j)) i++;
else j--;
}
双指针应用分类
常见问题分类:
(1) 对于一个序列,用两个指针维护一段区间
(2) 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作
最简单的应用
- 输入一个字符串,输出每个单词(以空格隔开)。
int n = strlen(str);
for(int i=0;i<n;i++)
{
int j=i;
while(j<n && str[j] != ' ') j++;
//这道问题的具体逻辑
for(int k=i;k<j;k++) cout<<str[k];
cout<<endl;
i=j;
}
- 无重复最长子序列
#include<iostream>
using namespace std;
int n;
const int N=100010;
int q[N],s[N];
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&q[i]);
int res=0;
// i是快指针,j为慢速指针
for(int i=0,j=0;i<n;i++)
{
s[q[i]] ++; //记录数组中元素出现的次数
while(s[q[i]]>1)
{
s[q[j]]--; //如果q[i]=q[j],则次数减1,j往后移动
j++;
}
res = max(res,i-j+1);
}
cout<<res<<endl;
return 0;
}