原题描述
+
给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。
注意:答案中不可以包含重复的四元组。
示例
输入:nums = [1,0,-1,0,-2,2], target=0
输出:[[-1,0,0,1],[-2,-1,1,2],[-2,0,0,2]]
原题链接:https://leetcode-cn.com/problems/4sum
思路解析
+
LeetCode中n数之和相关的题目有很多,除了两数之和以外,几乎都是同一种思路,所以弄懂其中一道题就可以刷其他题目了。
我们再回顾一下三数之和的基本思路:
1. 先将数组按照升序排序;
2. 以当前位置 作为三数之中的第一个数字(最小的数字),寻找他的其他两个伙伴,这两个伙伴一定处于 之后。我们使用两个可移动的指针 和 分别指向 和最后一一位数字,因为数组按升序排序,所以有两个基本事实:右移 会使和增大,左移 会使和减小。
到了四数之和,思路没有任何区别,只是又多了一层外循环而已。
关于排序+双指针的具体方法解析,我建议你直接看下面两篇文章。
复杂度分析
+
C++参考代码
+
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> res;
if (nums.size() < 4) return res;
sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size() - 3; ++i) {
if (i > 0 && nums[i] == nums[i-1]) continue;
for (int j = i + 1; j < nums.size() - 2; ++j) {
if (j > i + 1 && nums[j] == nums[j-1]) continue;
int l = j + 1, r = nums.size() - 1;
while (l < r) {
int curr_sum = nums[i] + nums[j] + nums[l] + nums[r];
if (curr_sum == target) {
res.push_back({nums[i], nums[j], nums[l], nums[r]});
while ((l < r) && (nums[l] == nums[l+1])) ++l;
while ((l < r) && (nums[r] == nums[r-1])) --r;
++l; --r;
}
else if (curr_sum > target) --r;
else ++l;
}
}
}
return res;
}
};