10.Two Pointers算法重难点剖析
1.two pointers
以一个例子引入:给定一个递增的正整数序列和一个正整数M,求序列中的两个不同位置的数a和b,使得它们的和恰好为M,输出所有满足条件的方案。例如给定序列{1,2,3,4,5,
6}和正整数M=8,就存在2+6=8与3+5=8成立。
本题的一个最直观的想法是,使用二重循环枚举序列中的整数a和b,判断它们的和是否为M,如果是,输出方案;如果不是,则继续枚举。代码如下:
for(int i=0;i<n;i++){
for(intj=i+1;j<n;j++){
if(a[i]+a[j]==M){
printf("%d %d\n",a[i],a[j]);
}
}
}
这种做法的时间复杂度为O(n2),对n在105的规模时是不可承受的。
以下是优化算法:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a[6]={1,2,3,4,5,6}; //升序数组
int x=6; //相加=x
int i=0,j=5; //i=0 j=n-1 n位数组长度
while(i<j)
{
if(a[i]+a[j]==x)
{
cout<<a[i]<<"+"<<a[j]<<"="<<x<<endl;
i++;
j--;
}
else if(a[i]+a[j]<x) i++;
else j--;
}
return 0;
}
2.序列合并优化
#include <bits/stdc++.h>
using namespace std;
int a[3]={1,2,3},b[3]={1,4,5},c[100]={}; //必须采用全局数组 否则就需要指针
int hebing(int a[],int b[],int c[],int n,int m)
{
int index=0,i=0,j=0;
while(i<n&&j<m)
{
if(a[i]<=b[j]) c[index++]=a[i++];
else c[index++]=b[j++];
}
while(i<n) c[index++]=a[i++];
while(j<m) c[index++]=b[j++];
return index; //返回合并后的数组的长度
}
int main()
{
for(int p=0;p<hebing(a,b,c,3,3);p++) cout<<c[p];
return 0;
}