class Solution2 { public: std::vector<std::vector<int>> threeSum(std::vector<int> nums, int target) { if (nums.size() < 3) { return std::vector<std::vector<int>>(); } std::sort(nums.begin(), nums.end()); std::vector<std::vector<int>> res; for (int i = 0; i < nums.size()-2; i++) { auto tuples = twoSum(nums, i+1, target-nums[i]); for (auto& x : tuples) { x.emplace_back(nums[i]); res.emplace_back(x); } while (i < nums.size()-2 && nums[i] == nums[i+1]) i++; } return res; }
private: std::vector<std::vector<int>> twoSum(const std::vector<int>& nums, int start, long int target) { if (nums.size() < 2) { return std::vector<std::vector<int>>(); } std::vector<std::vector<int>> res; int left = start, right = nums.size()-1; while (left < right) { int left_val = nums[left]; int right_val = nums[right]; int sum = left_val + right_val; if (sum == target) { res.push_back(std::vector<int>{left_val, right_val}); while (left < right && nums[left] == left_val) left++; while (left < right && nums[right] == right_val) right--; } else if (sum < target) { while (left < right && nums[left] == left_val) left++; } else { while (left < right && nums[right] == right_val) right--; } } return res; } };
class Solution { public: std::vector<std::vector<int>> fourSum(std::vector<int>& nums, long int target) { if (nums.size() < 4) { return std::vector<std::vector<int>>(); } std::vector<std::vector<int>> res; std::sort(nums.begin(), nums.end()); for (int i = 0; i < nums.size()-3; i++) { auto triples = threeSum(nums, i+1, target-nums[i]); for (auto& x : triples) { x.emplace_back(nums[i]); res.emplace_back(x); } while (i < nums.size()-3 && nums[i] == nums[i+1]) i++; } return res; }
private: std::vector<std::vector<int>> threeSum(std::vector<int> nums, int start, long int target) { if (nums.size() < 3) { return std::vector<std::vector<int>>(); } std::vector<std::vector<int>> res; for (int i = start; i < nums.size()-2; i++) { auto tuples = twoSum(nums, i+1, target-nums[i]); for (auto& x : tuples) { x.emplace_back(nums[i]); res.emplace_back(x); } while (i < nums.size()-2 && nums[i] == nums[i+1]) i++; } return res; }
std::vector<std::vector<int>> twoSum(const std::vector<int>& nums, int start, long int target) { if (nums.size() < 2) { return std::vector<std::vector<int>>(); } std::vector<std::vector<int>> res; int left = start, right = nums.size()-1; while (left < right) { int left_val = nums[left]; int right_val = nums[right]; int sum = left_val + right_val; if (sum == target) { res.push_back(std::vector<int>{left_val, right_val}); while (left < right && nums[left] == left_val) left++; while (left < right && nums[right] == right_val) right--; } else if (sum < target) { while (left < right && nums[left] == left_val) left++; } else { while (left < right && nums[right] == right_val) right--; } } return res; } };
/* 注意:调用这个函数之前一定要先给 nums 排序 */ vector<vector<int>> nSumTarget( vector<int>& nums, int n, int start, int target) {
int sz = nums.size(); vector<vector<int>> res; // 至少是 2Sum,且数组大小不应该小于 n if (n < 2 || sz < n) return res; // 2Sum 是 base case if (n == 2) { // 双指针那一套操作 int lo = start, hi = sz - 1; while (lo < hi) { int sum = nums[lo] + nums[hi]; int left = nums[lo], right = nums[hi]; if (sum < target) { while (lo < hi && nums[lo] == left) lo++; } else if (sum > target) { while (lo < hi && nums[hi] == right) hi--; } else { res.push_back({left, right}); while (lo < hi && nums[lo] == left) lo++; while (lo < hi && nums[hi] == right) hi--; } } } else { // n > 2 时,递归计算 (n-1)Sum 的结果 for (int i = start; i < sz; i++) { vector<vector<int>> sub = nSumTarget(nums, n - 1, i + 1, target - nums[i]); for (vector<int>& arr : sub) { // (n-1)Sum 加上 nums[i] 就是 nSum arr.push_back(nums[i]); res.push_back(arr); } while (i < sz - 1 && nums[i] == nums[i + 1]) i++; } } return res; }