首先说明双指针,何为双指针顾名思义就是序列中有两个指针来分别配合调控遍历这序列。
与其生硬讲解,不如举个例子。
例题:给定一段序列,里面有一些单词,并且每个单词都是以空格隔开。
题目要求是将每个单词为一行重新输出。
样例:ade scs sqq
共有三个单词,期望的输出是
ade
scs
sqq
这里我们就可以使用双指针算法来调控了,我们可以利用两个指针分别指向每个单词的起始和末尾,然后使用相应的下标去遍历题目给出的序列。
#include<iostream>
#include<string.h>
using namespace std;int main()
{char str[1000];gets(str);int n=str.size();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;}return 0;
}
通过我们可以通过这个题知道使用双指针算法的前提一定是具有单调性。
接下来我们来看一个例题:https://www.acwing.com/problem/content/801/
本题是要求寻找最长的连续不重复子序列,有单调性,可以使用双指针算法来完成。
本题的解题思路是寻找右指针i的左边最长的不重复子序列。
#include<iostream>
using namespace std;const int N=1e5+10;
int a[N],s[N];int main()
{int n;cin>>n;for(int i=0;i<n;i++){scanf("%d",&a[i]);}int ans=0;for(int i=0,j=0;i<n;i++){s[a[i]]++;while(j<=i && s[a[i]]>1){s[a[j]]--;j++;}ans=max(ans,i-j+1);}cout<<ans;return 0;
}
https://www.acwing.com/problem/content/802/
#include<iostream>
using namespace std;const int N=1e5+10;
int a[N],b[N];int main()
{int n,m,x;scanf("%d%d%d",&n,&m,&x);for(int i=0;i<n;i++) scanf("%d",&a[i]);for(int i=0;i<m;i++) scanf("%d",&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 && j>=0) cout<<i<<' '<<j; }return 0;
}