-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy path3-sum-closest.cc
107 lines (97 loc) · 2.54 KB
/
3-sum-closest.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// Copyright (c) 2013 Elements of Programming Interviews. All rights reserved.
#include <algorithm>
#include <cassert>
#include <iostream>
#include <iterator>
#include <random>
#include <string>
#include <vector>
using std::cout;
using std::default_random_engine;
using std::endl;
using std::numeric_limits;
using std::random_device;
using std::stoi;
using std::uniform_int_distribution;
using std::vector;
// @include
int three_sum_closest(vector<int> A, int target) {
sort(A.begin(), A.end());
int res = A[0] + A[1] + A[2];
for (size_t i = 0; i < A.size(); ++i) {
if (i == 0 || A[i] != A[i - 1]) {
size_t start = i + 1, end = A.size() - 1;
while (start < end) {
int sum = A[i] + A[start] + A[end];
if (sum == target) { // early return.
return sum;
}
if (abs(sum - target) < abs(res - target)) {
res = sum;
}
if (sum < target) {
++start;
} else {
--end;
}
}
}
}
return res;
}
// @exclude
void small_test() {
vector<int> A = {-3, -2, -5, 3, -4};
assert(three_sum_closest(A, -1) == -2);
}
int check_ans(vector<int> A, int target) {
sort(A.begin(), A.end());
int res = A[0] + A[1] + A[2];
for (size_t i = 0; i < A.size(); ++i) {
for (size_t j = i + 1; j < A.size(); ++j) {
for (size_t k = j + 1;
k < A.size() && A[i] + A[j] + A[k] - target <= abs(res - target);
++k) {
//cout << i << " " << j << " " << k << endl;
int sum = A[i] + A[j] + A[k];
if (sum == target) {
return sum;
}
if (abs(sum - target) < abs(res - target)) {
res = sum;
}
}
}
}
cout << "res = " << res << endl;
return res;
}
int main(int argc, char** argv) {
small_test();
default_random_engine gen((random_device())());
for (int times = 0; times < 2000; ++times) {
int n;
if (argc == 2) {
n = stoi(argv[1]);
} else {
uniform_int_distribution<int> n_dis(3, 100);
n = n_dis(gen);
}
uniform_int_distribution<int> A_dis(-1000, 1000);
vector<int> A;
generate_n(back_inserter(A), n, [&] { return A_dis(gen); });
/*
for (size_t i = 0; i < A.size(); ++i) {
cout << A[i] << " ";
}
cout << endl;
*/
uniform_int_distribution<int> target_dis(-4000, 4000);
int target = target_dis(gen);
cout << "target = " << target << endl;
int res;
cout << (res = three_sum_closest(A, target)) << endl;
assert(abs(res - target) == abs(target - check_ans(A, target)));
}
return 0;
}