四数之和
问题描述:
Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
问题分析:
此题的O(n^3)解法的思路跟 3Sum 基本没啥区别,就是多加了一层for循环,其他的都一样:
用set来进行去重复的处理还是有些取巧,可能在Java中就不能这么做,那么我们还是来看一种比较正统的做法吧,手动进行去重复处理。主要可以进行的有三个地方,首先在两个for循环下可以各放一个,因为一旦当前的数字跟上面处理过的数字相同了,那么找下来肯定还是重复的。之后就是当sum等于target的时候了,我们在将四个数字加入结果res之后,left和right都需要去重复处理,分别像各自的方面遍历即可。
算法实现:
略
参考代码:
用方法二来实现
法一:
vector<vector<int>> fourSum(vector<int> &nums, int target)
{
set<vector<int>> res;
sort(nums.begin(), nums.end());
for (int i = 0; i < int(nums.size() - 3); ++i)
{
for (int j = i + 1; j < int(nums.size() - 2); ++j)
{
if (j > i + 1 && nums[j] == nums[j - 1])
continue;
int left = j + 1, right = nums.size() - 1;
while (left < right)
{
int sum = nums[i] + nums[j] + nums[left] + nums[right];
if (sum == target)
{
vector<int> out{nums[i], nums[j], nums[left], nums[right]};
res.insert(out);
++left; --right;
} else if (sum < target)
{
++left;
}
else
{
--right;
}
}
}
}
return vector<vector<int>>(res.begin(), res.end());
}
法二:
vector<vector<int>> fourSum(vector<int> &nums, int target)
{
vector<vector<int>> res;
int n = nums.size();
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 left = j + 1, right = n - 1;
while (left < right)
{
int sum = nums[i] + nums[j] + nums[left] + nums[right];
if (sum == target)
{
vector<int> out{nums[i], nums[j], nums[left], nums[right]};
res.push_back(out);
while (left < right && nums[left] == nums[left + 1])
{
++left;
}
while (left < right && nums[right] == nums[right - 1])
{
--right;
}
++left;
--right;
} else if (sum < target)
{
++left;
}
else
{
--right;
}
}
}
}
return res;
}