-
Notifications
You must be signed in to change notification settings - Fork 0
/
18_4sum.cpp
130 lines (120 loc) · 4 KB
/
18_4sum.cpp
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
// Solution 1: Brute force to find all combinations of 4 numbers
// Time complexity: O(n^3)
class Solution_1 {
public:
vector<vector<int>> fourSum(vector<int> &nums, int target) {
if (nums.size() < 4)
return {};
// sort the input vector
sort(nums.begin(), nums.end());
// initialize the result vector
vector<vector<int>> res;
// iterate through the input vector
for (int i = 0; i < nums.size(); i++) {
// Handle case when the number is overflown
if (nums[i] > 0 && nums[i] > target)
break;
// skip duplicates
if (i > 0 && nums[i] == nums[i - 1])
continue;
// iterate through the input vector
for (int j = i + 1; j < nums.size(); j++) {
// skip duplicates
if (j > i + 1 && nums[j] == nums[j - 1])
continue;
// initialize the left and right pointers
int left = j + 1, right = nums.size() - 1;
// iterate through the input vector
while (left < right) {
// calculate the sum of the four numbers
long long sum = nums[i] + nums[j] + nums[left] + nums[right];
// if the sum is equal to the target
if (sum == target) {
// add the four numbers to the result vector
res.push_back({nums[i], nums[j], nums[left], nums[right]});
// skip duplicates
while (left < right && nums[left] == nums[left + 1])
left++;
// skip duplicates
while (left < right && nums[right] == nums[right - 1])
right--;
// move the left pointer to the right
left++;
// move the right pointer to the left
right--;
}
// if the sum is less than the target
else if (sum < target)
// move the left pointer to the right
left++;
// if the sum is greater than the target
else
// move the right pointer to the left
right--;
}
}
}
return res;
}
};
// Solution 2: Optimize the solution 1 add some conditions to skip some
// unnecessary iterations
// Time complexity: O(n^3)
class Solution_2 {
public:
vector<vector<int>> fourSum(vector<int> &nums, int target) {
vector<vector<int>> result;
if (nums.size() < 4)
return result;
sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size() - 3; i++) {
if (i > 0 && nums[i] == nums[i - 1])
continue;
if ((long long)nums[i] + (long long)nums[i + 1] + (long long)nums[i + 2] +
(long long)nums[i + 3] >
target)
break;
if ((long long)nums[i] + (long long)nums[nums.size() - 1] +
(long long)nums[nums.size() - 2] +
(long long)nums[nums.size() - 3] <
target)
continue;
for (int j = i + 1; j < nums.size() - 2; j++) {
if (j > i + 1 && nums[j] == nums[j - 1])
continue;
if ((long long)nums[i] + (long long)nums[j] + (long long)nums[j + 1] +
(long long)nums[j + 2] >
target)
break;
if ((long long)nums[i] + (long long)nums[j] +
(long long)nums[nums.size() - 1] +
(long long)nums[nums.size() - 2] <
target)
continue;
int left = j + 1, right = nums.size() - 1;
while (left < right) {
long long sum = static_cast<long long>(nums[i]) + nums[j] +
nums[left] + nums[right];
if (sum == target) {
result.push_back({nums[i], nums[j], nums[left], nums[right]});
while (left < right && nums[left] == nums[left + 1])
left++;
while (left < right && nums[right] == nums[right - 1])
right--;
left++;
right--;
} else if (sum < target) {
left++;
} else {
right--;
}
}
}
}
return result;
}
};