题目链接:https://leetcode.cn/problems/4sum/
1.排序+双指针
class Solution {
using ll = long long;
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
int n = nums.size();
vector<vector<int>> res;
if (n < 4) return res;
sort(nums.begin(), nums.end()); // 对数组进行排序
for (int i = 0; i < n - 3; i++) {
if (i > 0 && nums[i] == nums[i - 1]) continue; // 跳过第一个数的重复数字
for (int j = i + 1; j < n - 2; j++) {
if (j > i + 1 && nums[j] == nums[j - 1]) continue; // 跳过第二个数的重复数字
int l = j + 1, r = n - 1;
while (l < r) {
ll t = (ll)nums[i] + nums[j] + nums[l] + nums[r];
if (t < target) {
l++;
} else if (t > target) {
r--;
} else {
res.push_back({nums[i], nums[j], nums[l], nums[r]});
l++;
r--;
while (l < r && nums[l] == nums[l - 1]) l++; // 跳过第三个数的重复数字
while (l < r && nums[r] == nums[r + 1]) r--; // 跳过第四个数的重复数字
}
}
}
}
return res;
}
};
2.对上面代码加剪枝
class Solution {
using ll = long long;
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
int n = nums.size();
vector<vector<int>> res;
if (n < 4) return res;
sort(nums.begin(), nums.end()); // 对数组进行排序
for (int i = 0; i < n - 3; i++) {
if (i > 0 && nums[i] == nums[i - 1]) continue; // 跳过第一个数的重复数字
if ((ll)nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) break; // 剪枝一
if ((ll)nums[i] + nums[n - 3] + nums[n - 2] + nums[n - 1] < target) continue; // 剪枝二
for (int j = i + 1; j < n - 2; j++) {
if (j > i + 1 && nums[j] == nums[j - 1]) continue; // 跳过第二个数的重复数字
if ((ll)nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) break; // 剪枝三
if ((ll)nums[i] + nums[j] + nums[n - 2] + nums[n - 1] < target) continue; // 剪枝四
int l = j + 1, r = n - 1;
while (l < r) {
ll t = (ll)nums[i] + nums[j] + nums[l] + nums[r];
if (t < target) {
l++;
} else if (t > target) {
r--;
} else {
res.push_back({nums[i], nums[j], nums[l], nums[r]});
l++;
r--;
while (l < r && nums[l] == nums[l - 1]) l++; // 跳过第三个数的重复数字
while (l < r && nums[r] == nums[r + 1]) r--; // 跳过第四个数的重复数字
}
}
}
}
return res;
}
};