Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array
which gives the sum of zero.Note:
The solution set must not contain duplicate triplets.
Example:
Given array nums = [-1, 0, 1, 2, -1, -4],
A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]
求一个数组内任意3个数的和为0的组合方案。
1、暴力求解(超时)
vector<vector<int>> threeSum(vector<int>& nums) {
int len = nums.size();
vector<vector<int>> ret;
int index = 0;
for(int i = 0;i<len;i++)
{
for(int j = 0;j<len;j++)
{
if(j != i)
{
for(int k = 0;k<len;k++)
{
if(k != i && k != j)
{
if(nums[i] + nums[j] + nums[k] == 0)
{
ret[index].push_back(nums[i]);
ret[index].push_back(nums[j]);
ret[index].push_back(nums[k]);
index++;
}
}
}
}
}
}
return ret;
}
2、首先将输入的数组排序;求三个数(i,j,k)的和等于0,可以等价成为求j+k的和等于-i的问题;
而求j+k的问题,在已经排序的数组中,通过首尾两个指针控制和与target的大小。
vector<vector<int>> threeSum(vector<int>& nums) {
int len = nums.size();
vector<vector<int>> ret;
if (len < 3)
return ret;
sort(nums.begin(),nums.end()); //数组排序
for(int i = 0;i<len-2;i++)
{
if(i == 0 || (i > 0 && nums[i] != nums[i - 1])) //如果有重复的数字,那么没有必要重复计算
{
int left = i + 1; //left和right是在i后面的子数组的首尾指针
int right = len-1;
int tar = 0 - nums[i];
while(left < right)
{
if(nums[left] + nums[right] == tar) //相等即为和为0的三个数
{
vector<int> tmp;
tmp.push_back(nums[i]);
tmp.push_back(nums[left]);
tmp.push_back(nums[right]);
ret.push_back(tmp);
while(left < right && nums[left] == nums[left+1]) //还是去除重复的计算
left++;
while(left < right && nums[right] == nums[right-1])
right--;
left++;
right--;
}
else if(nums[left] + nums[right] > tar) //如果大于target,那么尾指针--
right--;
else
left++;
}
}
}
return ret;
}