Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
- Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
- The solution set must not contain duplicate triplets.
For example, given array S = {-1 0 1 2 -1 -4}, A solution set is: (-1, 0, 1) (-1, -1, 2)
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
if(nums.size() < 3) return result;
sort(nums.begin(), nums.end());
const int target = 0;
auto last = nums.end();
for(auto i = nums.begin(); i < last - 2; ++i){
if(i > nums.begin() && *i == *(i - 1)) continue;
auto j = i + 1;
auto k = nums.end() - 1;
while(j < k){
if(*i + *j + *k < target){
++j;
while(*j == *(j - 1) && j < k) ++j;
}
else if(*i + *j + *k > target){
--k;
while(*k == *(k + 1) && j < k) --k;
}
else{
result.push_back({*i, *j, *k});
++j;
--k;
while(*j == *(j - 1) && j < k) ++j;
}
}
}
return result;
}
};
超时的解法,两次排序了用unique去重
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
if(nums.size() < 3) return result;
sort(nums.begin(), nums.end());
const int target = 0;
auto last = nums.end();
for(auto i = nums.begin(); i < prev(last, 2); ++i){
auto j = next(i);
auto k = prev(last);
while(j < k){
if(*i + *j + *k < target){
++j;
}
else if(*i + *j + *k > target){
--k;
}
else{
result.push_back({*i, *j, *k});
++j;
--k;
}
}
}
sort(result.begin(), result.end());
result.erase(unique(result.begin(), result.end()), result.end());
return result;
}
};
Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
For example, given array S = {-1 2 1 -4}, and target = 1. The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
class Solution { public: int threeSumClosest(vector<int>& nums, int target) { sort(nums.begin(), nums.end()); int result; bool flag = false; int min_gap = abs(nums[0] + nums[1] + nums[2] - target); for(auto i = nums.begin(); i < nums.end() - 2; ++i){ auto j = next(i); auto k = prev(nums.end()); while(j < k){ int sum = *i + *j + *k; int gap = abs(sum - target); if(gap <= min_gap){ result = sum; min_gap = gap; if(gap == 0){ flag = true; break; } } if(sum < target) ++j; else --k; } if(flag) break; } return result; } };
Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
Note:
- Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
- The solution set must not contain duplicate quadruplets.
For example, given array S = {1 0 -1 0 -2 2}, and target = 0. A solution set is: (-1, 0, 0, 1) (-2, -1, 1, 2) (-2, 0, 0, 2)class Solution { 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(auto i = nums.begin(); i < nums.end() - 3; ++i){ for(auto j = next(i); j < nums.end() - 2; ++j){ auto k = next(j); auto l = prev(nums.end()); while(k < l){ int sum = *i + *j + *k + *l; if(sum == target){ result.push_back({*i, *j, *k, *l}); do{ ++k; }while(*k == *(k - 1) && k < l); do{ --l; }while(*l == *(l + 1) && k < l); } else if(sum < target) ++k; else --l; } } } sort(result.begin(), result.end()); result.erase(unique(result.begin(), result.end()), result.end()); return result; } };