800. 数组元素的目标和
caution
思路
先写暴力写法,然后优化暴力。
设目标值为
由题目可以知道,这个序列是升序的,所以当固定一个指针 ,移动另一个指针 的时候,如果相加起来比 大,说明 往后的不可能找到 (因为一个 中最小的数加上一个 中最大的数都比 大,那么不可能在 中找到另一个数加起来比 小),所以 要往前找,故可以想到指针从后往前移动。只有当相加起来比 小的时候,说明此处 指向的就是最接近 的值,那么固定指针 就可以向前移动了。
换句话说,只要相加起来还比目标值要大,那么就继续往前,也就是 j--
。
代码
暴力:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, m, x;
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];
int flag = 0, p1, p2;
for (int i = 0, j = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (a[i] + b[j] == x) {
p1 = i, p2 = j;
break;
}
}
}
cout << p1 << " " << p2 << endl;
return 0;
}
双指针优化:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, m, x;
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];
int flag = 0, p1, p2;
for (int i = 0, j = m - 1; i < n; i++) {
while (j >= 0 && a[i] + b[j] > x) j--;
if (j >= 0 && a[i] + b[j] == x) {
p1 = i, p2 = j;
break;
}
}
cout << p1 << " " << p2 << endl;
return 0;
}