Copy Input: nums = [1,0,-1,0,-2,2], target = 0
Output: [[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
Copy Input: nums = [], target = 0
Output: []
Copy class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> quad;
const int n = nums.size();
if (n < 4) return quad;
sort(nums.begin(), nums.end());
unordered_set<int> seen;
seen.reserve(n);
for (int i = 0; i < n; ++i) {
if (i > 0 && nums[i] == nums[i - 1]) continue;
for (int j = i + 1; j < n; ++j) {
if (j > i + 1 && nums[j - 1] == nums[j]) continue;
for (int k = j + 1; k < n; ++k) {
const int sum = target-nums[i]-nums[j]-nums[k];
if (seen.find(sum) != seen.end()) {
quad.push_back({nums[i], nums[j], sum, nums[k]});
while (k + 1 < n && nums[k] == nums[k + 1]) ++k;
}
seen.insert(nums[k]);
}
seen.clear();
}
}
return quad;
}
};
Copy class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
return kSum(nums, 0, 4, target);
}
vector<vector<int>> kSum(vector<int>&nums, int start, int k, int target) {
vector<vector<int>> combs;
if (k == 2) return twoSum(nums, start, target);
for (int i = start; i < nums.size(); ++i) {
if (i > start && nums[i - 1] == nums[i]) continue;
auto _combs = kSum(nums, i + 1, k - 1, target - nums[i]);
for (auto &comb: _combs) {
comb.push_back(nums[i]);
combs.push_back(comb);
}
}
return combs;
}
vector<vector<int>> twoSum(vector<int>&nums, int start, int target) {
vector<vector<int>> combs;
int end = nums.size() - 1;
while (start < end) {
const int sum = nums[start] + nums[end];
if (sum == target) {
combs.push_back({nums[start++], nums[end--]});
while (start < end && nums[start - 1] == nums[start]) ++start;
while (start <= end && nums[end] == nums[end + 1]) --end;
} else if (sum < target){
++start;
} else {
--end;
}
}
return combs;
}
};