核心用途:将朴素算法优化 (所有双指针算法的时间复杂度都是O(n)
例1:输入字符串,空格隔开单词,输出每一个单词
#include<iostream>
#include<string.h>
using namespace std;
int main(){
char str[1000];
gets(str);
for(int i = 0; i<n; i++ ){
int j=i;//j指向i所在的地方
while(j<n && str[j]!=' ')j++;//j没有越界且j指向的位置不是空格时,j移动
for(int k=i;k<j;k++)cout<<str[k];//输出i,j之间的字母,此时i指向单词的开始,j指向空格
cout<<endl
i=j;//i指向空格处
//本次循环结束后,i++,i指向下一个单词的开始
}
return 0;
}
例2 :P 799,最长连续不重复子序列
双指针算法一般先从暴力开始想,最后用双指针进行优化
先枚举终点,再枚举起点
i是终点,j是起点
#include<iostream>
using namespace std;
const int N=100010;
int n;
int a[N];
int s[N];//存了当前【j,i】这个区间里面,每个数出现的次数
int main(){
cin >> n;
for(int i=0; i<n; i++) cin >> a[i];
int res = 0;
for(int i = 0, j = 0; i < n; i++ ){
s[a[i]]++;//记录a[i]这个数出现的次数
while(s[a[i]]> 1){
//如果这个数出现两遍,j就开始右移,直到i,j指向同一个数
s[a[j]]--;//每一个都减减,是为了j移动到重复数字前面那个数字的时候时,s[a[i]]--,可以跳出循环
j++;//此时i,j指向同一个位置
}
res = max(res, i-j+1);
}
cout << res <<endl;
return 0;
}