双指针问题是一中算法思路主要用于通过空间换时间,将原本的双循环时间复杂度O(n^2)简化为O(n);
题目一
解题思路
依然是空间换时间,设立一个temp数组用于存储在当前最大序列种每个元素的个数,当检查到新加入元素在当前最大子序列中的个数(temp[a[i]])大于1时,将 j向右移动至重复元素之右。
代码模板
#include<iostream>
using namespace std;
const int N=1e5+10;
int a[N],temp[N];
int main()
{
int n,m,res=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
for(int i=0,j=0;i<n;i++)
{
temp[a[i]]++;
while(temp[a[i]]>1)
{ temp[a[j]]--;
j++;
}
res=max(i-j+1,res);
}
printf("%d",res);
return 0;
}
题目二
解题思路
利用两个数组都是单调递增的特性,有这样的性质:A[i]+B[j]>=x 则B[j+1]到B[m]不可能与当前A[i]匹配。故以递减来求取 j .
此题的其他解法https://www.acwing.com/solution/content/138481/
代码模板
#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(A[i]+B[j]>x&&j>=0)j--;
if(A[i]+B[j]==x&&j>=0)printf("%d %d\n",i,j);
}
return 0;
}
题目三
解题思路
代码模板
#include<iostream>
using namespace std;
const int N=1e5+10;
int n,m;
int A[N],B[N];
int main()
{
scanf("%d%d",&n,&m);
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=0;j<m;j++)
{
if(A[i]==B[j]&&i<n)i++;
if(i==n){printf("Yes\n");return 0;}
}
printf("No\n");
return 0;
}