双指针
这个问题的解决方式比较多样:
1. 最简单的办法是枚举序列A中的每一个元素a,然后找到序列B中的元素b=x−a,由于两序列都是升序的,因此可以二分查找,时间复杂度为O(n∗logn),空间复杂度为O(1);
2. 还可以把序列A中的每个元素存入哈希表,然后枚举序列B中的每一个元素,查找x−b是否在哈希表中,时空间复杂度都为O(n);
3. 接下来着重介绍双指针法,时间复杂度同样为O(n),但是空间复杂度仅O(1)。
条件ai+bi==x可以分为两半来看
1. a+bi≤x:序列A中元素已确定,当某个bi满足了条件1时,可以确定序列B从i+1位开始的后缀中,每个元素都不满足条件1,i只有继续减少才可能继续满足;
2. ai+b≥x:序列B中元素已确定,当某个ai满足条件2时,序列A在以i−1位为末端的前缀中,每个元素都不满足条件2,i只能继续增加才可能继续满足;
因此,初始化双指针(i,j)索引对时,i指向序列A的头端,j指向序列B的尾端(也可以反过来)。当i和j都没有越界时,每次循环检查ai+bj是否等于目标和x,偏大则减少j,偏小则增加i,直到相等(一定存在)
C++ 代码
#include <iostream>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n, m, x;
cin >> n >> m >> x;
int* a = new int[n], * b = new int[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 = m - 1;
while(i < n && j >= 0) {
if(a[i] + b[j] == x) {
cout << i << " " << j << endl;
return 0;
}
else if(a[i] + b[j] > x) {
j--;
}
else {
i++;
}
}
delete[] a;
delete[] b;
return 0;
}