给定两个升序排序的有序数组 A 和 B,以及一个目标值 x。
数组下标从 0 开始。
请你求出满足 A[i]+B[j]=x 的数对 (i,j)。
数据保证有唯一解。
输入格式
第一行包含三个整数 n,m,x,分别表示 A 的长度,B 的长度以及目标值 x。
第二行包含 n 个整数,表示数组 A。
第三行包含 m 个整数,表示数组 B。
输出格式
共一行,包含两个整数 i 和 j。
数据范围
数组长度不超过 10^5。
同一数组内元素各不相同。
1≤数组元素≤10^9
输入样例:
4 5 6
1 2 4 7
3 4 6 8 9
输出样例:
1 1
一开始想了比如借助hashmap、一个顺序一个二分...艹,这题肯定不是想考这个啊。后来想到一个从0开始一个从m-1开始不就行了
方法一:
思路:双指针,初始A[i=0],B[j=m-1]
- 若
x == A[i] + B[j]
,输出 - 若
x < A[i] + B[j]
,因为数组是升序的,所以要i--
或j--
,此时 i 再减就溢出了,所以让 j-- - 若
x > A[i] + B[j]
,同理,让 i++
补充:为什么这样不会漏情况呢
- 原因一:根据上面的思路,如果某次由于
x > A[i] + B[j]
i++ 后,变成了x < A[i] + B[j]
,此时可以选择i--
或j--
,如果 i-- 的话,那不就是打回原形原地反复横跳吗23333,所以要进行 j-- - 原因二:所以,如果一个指针到达了最终位置,那么接下来移动的肯定是另一个指针,最终也会到达正确的位置
#include <bits/stdc++.h>
using namespace std;
int n, m, x;
int a[100010], b[100010];
int main() {
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]);
int i = 0, j = m - 1, t = a[i] + b[j];
while (t != x) {
if (t > x) j--;
else i++;
t = a[i] + b[j];
}
printf("%d %d", i, j);
}