问题描述
给定 n n n 个数 a 1 a_1 a1、 a 2 a_2 a2 … a n a_n an,要求判断这组数里是否存在某两个数(可以重复选取同一个数)的和为 s u m sum sum。
数据规模
1
≤
n
≤
100000
1 \le n \le 100000
1≤n≤100000
1
≤
a
i
≤
10000
1 \le a_i \le 10000
1≤ai≤10000
1
≤
s
u
m
≤
1000000000
1 \le sum \le 1000000000
1≤sum≤1000000000
样例输入
2 3 4 5
样例输出
YES
问题求解
很简单的一个思路是枚举出所有的情况,一一和 sum 比较,但是这样算法的复杂度是
O
(
n
2
)
O(n^2)
O(n2),无法完成需求,所以必须简化算法。
想一下:
a
+
b
=
s
u
m
a + b = sum
a+b=sum 可以转化为
a
=
s
u
m
−
b
a = sum - b
a=sum−b,所以我们可以利用二分查找来简化算法,代码如下:
#include <iostream>
#include <algorithm>
using namespace std;
const int NUM = 1e5 + 50;
int a[NUM];
int n;
int sum;
void solve() {
sort(a, a + n);
for (int i = 1; i <= n; ++i) {
int diff = sum - a[i];
if (binary_search(a, a + n, diff)) {
cout << "YES" << endl;
return;
}
}
cout << "NO" << endl;
}
int main(int argc, char** argv) {
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
}
cin >> sum;
solve();
return 0;
}