-
Notifications
You must be signed in to change notification settings - Fork 0
/
three_sum.cc
54 lines (45 loc) · 1.67 KB
/
three_sum.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
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
std::vector<std::vector<int>> sol;
std::unordered_set<int> ht;
for (int i = 0; i < nums.size(); i++) {
// If target has already been seen, no need to re do this.
if (ht.find(nums.at(i)) != ht.end())
continue;
ht.emplace(nums.at(i));
int tar = -1 * nums.at(i);
// Is there a 2 sum with target = -nums[i]?
std::vector<std::vector<int>> twoSum = hasTwoSum(nums, i, tar);
if (!twoSum.empty()) {
sol.insert(sol.end(), twoSum.begin(), twoSum.end());
}
}
sort(sol.begin(), sol.end());
auto ip = std::unique(sol.begin(), sol.end());
sol.resize(std::distance(sol.begin(), ip));
return sol;
}
private:
vector<vector<int>> hasTwoSum(vector<int> &nums, int pos, int target) {
std::unordered_map<int, int> ht;
std::vector<std::vector<int>> vec;
int t = -1 * target; // Original number
for (int i = 0; i < nums.size(); i++) {
if (i == pos) continue;
ht.emplace(nums[i], i);
}
for (int i = 0; i < nums.size(); i++) {
if (i == pos) continue;
auto it = ht.find(target - nums.at(i));
if (it != ht.end() && it->second != i) {
// 2 sum candidate
vector<int> v{t, nums.at(i), it->first};
// Since there's always only 3 elements, sorting is constant time
sort(v.begin(), v.end());
vec.push_back(v);
}
}
return vec;
}
};