刚开始写暴力过不了,因为两层循环,,题目的最大范围是1e5:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
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 j=0;j<m;j++)cin>>b[j];
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(a[i]+b[j]==x)
{
cout<<i<<" "<<j<<endl;
}
}
}
return 0;
}
这个时候我们发现数组具有单调性,即是升序数组,那么我们可以用双指针来做,降低时间复杂度。
当a[i]+a[j]大于x的时候,j就向左移:
如下,j会一直移到下标1的位置,此时a[i]+a[j]才小于x:
此时我们让i指针向右移:
这个时候我们发现a[i]+a[j]==x了,那么就输出i,j,然后结束循环。
code
第一层循环是O(n),第二层循环因为j从m到0,所以是O(m),因为j总共就执行m次,而不是i执行好一次j就要执行m次。所以是线性的,复杂度为O(n+m),而不是O(n*m)
#include<bits/stdc++.h>
using namespace std;
int n,m,x;
const int N=1e5+10;
int a[N],b[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++)
{
//如果大于那就一直左移 直到小于等于x才停止
while(j>=0&&a[i]+b[j]>x)j--;
// 这个时候判断一下
if(a[i]+b[j]==x)cout<<i<<" "<<j<<endl;
}
return 0;
}