Double pointer refers to that in the process of traversing objects, instead of using a single pointer for access, two pointers in the same direction (fast and slow pointer) or opposite directions (collision pointer) are used to scan, so as to achieve the corresponding purpose. .
Example:
AcWing 799. The longest continuous non-repeating subsequence
Given an integer sequence of length n, find the longest continuous interval that does not contain repeated numbers, and output its length.
Method:
open an array vis to record the number of numbers that appeared in the interval [i,j], when i moves forward, add a[i] to the interval vis[a[i]]++, if vis is found [a[i]]>1, that is to say, the number of occurrences of a[i] in the interval is greater than 1 (meaning that there is a repeated number), then the left pointer j will move backward, and vis[a [j]]- -, because after j moves one back, a[j] pointed to by j is no longer in the interval [j,i] until vis[a[i]]==1, j stops moving , Update ans at this time, record the maximum length of the interval
const int N = 1e5+5;
int n,a[N],vis[N];
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
int ans=0;
for(int i=1,j=1;i<=n;i++)
{
vis[a[i]]++;
while(vis[a[i]]>1) vis[a[j++]]--;//等价于vis[a[j]]--,j++;
ans=max(ans,i-j+1);
}
cout<<ans<<endl;
return 0;
}
Example:
AcWing 800. Target sum of array elements
Given two ordered arrays A and B sorted in ascending order, and a target value x. The array index starts from 0.
Please find the number pair (i, j) satisfying A[i] + B[j] = x.
The data is guaranteed to have a unique solution.
Practice: The
problem is to ensure that the array is arranged in ascending order. We can use this monotonicity, using a double pointer, the pointer i points to the beginning of the A array, and the pointer j points to the end of the B array, and then start checking, if a[i]+b[j] >x, then due to the monotonicity of the array, j must move forward by j- -; if a[i]+b[j]<x, the same, i must move backward by one, i++; if a[i ]+b[j]==x, you can output (i, j) and break
const int N = 1e5+5;
int n,m,x,b[N],a[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<<endl;
break;
}
}
return 0;
}
It can also be written like this:
const int N = 1e5+5;
int n,m,x,b[N],a[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];
int i=0,j=m-1;
while(i<n&&j>=0)
{
if(a[i]+b[j]==x) break;
else if(a[i]+b[j]>x) j--;
else if(a[i]+b[j]<x) i++;
}
cout<<i<<" "<<j<<endl;
return 0;
}
Example:
AcWing 2816. Judge subsequence
Given a sequence of integers a1, a2,...,an with length n, and a sequence of integers b1,b2,...,bm with length m.
Please judge whether a sequence is a subsequence of b sequence.
A subsequence refers to a sequence obtained by arranging part of the items in the original order. For example, the sequence {a1, a3, a5} is a subsequence of the sequence {a1, a2, a3, a4, a5}.
Method:
because it is necessary to determine whether a is a subsequence of b, you can set a pointer i to point to the head of the a array, pointer j to point to the head of the b array,
and then traverse the b array, each time judging whether the current a[i] is the same as b[ j] is equal, if a[i]==b[j], then i++;
after the final traversal, judge whether i is equal to n, if it is equal, it means that each number in the a array can be in order in the b array Found, output Yes, otherwise, No
const int maxn = 1e5+5;
int n,m;
int a[maxn],b[maxn];
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++) cin>>a[i];
for(int i=0;i<m;i++) cin>>b[i];
int i=0,j=0;
while(i<n&&j<m)
{
if(a[i]==b[j]) i++;
j++;
}
if(i==n) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
return 0;
}