题目大意:在给出的数组中找出四个数,使他们的和等于目标数值
分析:K sum问题,排序+双指针。和leetcode15、16一个类型。4sum在3sum的基础上加一层循环即可,为了提高效率,有两个小判断能剪枝。
代码:
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> ans;
if (nums.size() < 4) return ans;
sort(nums.begin(), nums.end());
int n = nums.size();
for (int i = 0;i < nums.size() - 3;i++) {
if (i > 0 && nums[i] == nums[i - 1])
continue;
if (nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target)
break; //所有可取值中的最小和大于目标值,不可能再有答案,退出循环
if (nums[i] + nums[n - 3] + nums[n - 2] + nums[n - 1] < target)
continue; //最大和小于目标值,对i来说和不够大,跳过i继续循环
for (int j = i + 1;j < nums.size() - 2;j++) {
if (j > i + 1 && nums[j] == nums[j - 1])
continue;
if (nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target)
break;
if (nums[i] + nums[j] + nums[n - 2] + nums[n - 1] < target)
continue;
int l = j + 1;
int r = nums.size() - 1;
while (l < r) {
vector<int> tmp;
if (nums[i] + nums[j] + nums[l] + nums[r] == target) {
tmp.push_back(nums[i]);
tmp.push_back(nums[j]);
tmp.push_back(nums[l]);
tmp.push_back(nums[r]);
ans.push_back(tmp);
while (l < r && nums[l] == nums[l + 1])
l++;
while (l < r && nums[r] == nums[r - 1])
r--;
l++, r--;
}
else if (nums[i] + nums[j] + nums[l] + nums[r] < target)
l++;
else r--;
}
}
}
return ans;
}
};