1、滑动窗口
例题:
给定一个长度为 n 的整数序列,请找出最长的不包含重复的数的连续区间,输出它的长度。
解法:
维护一个从j到i的窗口,里面全是不重复数。初始将i和j都设为0,指向数组起始元素。然后开始遍历数组i:0—>n,并记录每个元素出现的次数,如果此时元素c出现了第两次,则让j开始向后移,直到窗口里面只有一个元素c。
代码:
int a[N];//数组a为整数序列
int b[N];//数组b记录每个元素的出现次数 可以用hashmap
int main ()
{
int n;cin>>n;
for(int i=0;i<n;i++)cin>>a[i];
int i,j=0;
int res=0;//res记录最长不重复序列长度
for(i=0;i<n;i++)
{
int c = a[i];//当前遍历的元素为c
b[c]++;//元素c的出现次数+1
while(b[c]>1)//若元素c的次数不为1 让j++ 窗口缩小 知道窗口里面只有一个c
{
b[a[j]]--;//元素a[j]的数量-1
j++;//窗口右移
}
res=max(res,i-j+1);//统计此时窗口大小
}
cout<<res;
}2、双指针
例题
给定两个升序排序的有序数组 a和 b,以及一个目标值 x。
数组下标从 0 开始。
请你求出满足 a[i]+b[j]=x 的数对 (i,j)。
数据保证有唯一解。
解法:
由于数组a、b有序,考虑双指针:i指向a数组的第一个元素,j指向b数组的最后一个元素。
如果a[i]+b[j]>x 令j-1(指针左移)此时值太大了 要减小
如果a[i]+b[j]<x 令i+1(指针右移)此时值太小了 要增大
代码:
int a[N],b[N];
int main(){
int n,m,x;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(a[i]+b[j]!=x)
{
if(a[i]+b[j]>x)
j--;
else
i++;
}
cout<<i<<" "<<j<<endl;
}