数组元素的目标和

这道题可以双指针、哈希,但也可以二分,这里就把三种一起讲掉啦!

二分

二分思路

既然要找两个和为 $x$ 的数,那么我们可以把它转换成确定了一个 $y$ 为 $A_i$ 然后快速在 $B$ 中找出 $x - y$ 的问题。
显然我们可以二分查找,算法复杂度为 $O(nlogn)$,可以 $AC$ 。

代码

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 100010;
int a[N], b[N];
int n, m, x;

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; i < n; i ++) {
int y = x - a[i];
int l = 0, r = m - 1;
while (l <= r) {
int mid = l + r >> 1;
if (b[mid] == y) {
cout << i << " " << mid << endl;
return 0;
} else if (b[mid] < y) {
l = mid + 1;
} else {
r = mid - 1;
}
}
}
return 0;
}

双指针

双指针思路

我们先简化一下问题,变成求 $A_i + B_j >= x$ 且 $j$ 要最小。
我们用可以一个指针 $i$ 枚举 $A$ 中的所有数,而 $j$ 则用来枚举 $B$,但由于数组是单调递增的,所以如果 $A_i + B_j \ge x$ 那么 $B_{j + 1}$ 到 $B_m$ 就不可能是答案。
所以 $j$ 是只能递减的,如此,我们便可以用 $O(n + m)$ 的时间复杂度通过这道题。

代码

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 100010;
int n, m, x;
int a[N], b[N];

int main() {
cin >> n >> m >> x;
for (int i = 1; i <= n; i ++) cin >> a[i];
for (int i = 1; i <= m; i ++) cin >> b[i];
for (int i = 1, j = m; i <= n; i ++) {
while (j >= 0 && a[i] + b[j] >= x) j --;
if (j >= 0 && b[j + 1] + a[i] == x)
cout << i - 1 << " " << j << endl;
}
return 0;
}

哈希

思路

我们可以在输入 $A$ 时把每个数存进哈希表里,对于每个输入的 $B_i$ 看看 $x - B_i$ 是否出现与哈希表即可。

代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>

using namespace std;

const int N = 100010;
int n, m, x;
int a[N], b[N];
unordered_map<int, int> h;

int main() {
cin >> n >> m >> x;
for (int i = 0; i < n; i ++) {
cin >> a[i];
h[a[i]] = i;
}
for (int i = 0; i < m; i ++) {
cin >> b[i];
if (h.count(x - b[i]))
cout << h[x - b[i]] << " " << i << endl;
}
return 0;
}

好啦,这篇题解到这里就结束啦!感谢观看!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值