给定一个包含 n 个整数的数组 nums
,判断 nums
中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
解题思路:
不使用暴力解法,核心思想首先要把条件分解,三个数之和为0则至少有一个数为负数,按照选定一个数再寻找两个与之匹配的数的思路,先把数组排序,然后遍历所有的负数,遇到第一个正数就可以停止遍历,因为后面的数都是正数。这样减少了循环嵌套层数和循环次数。
vector<vector<int>> Solution::threeSum(vector<int>& nums)
{
vector<vector<int>> res;
//vector<int> temp;
/*1.先对数组进行排序,因为三数之和为0,必然至少有一个数为负数*/
sort(nums.begin(), nums.end());
/*2.遍历有序数组,选取第一个负数*/
for(int k = 0; k < nums.size() - 1; k ++)
{
/*3.如果遍历到第一个正数,说明后面的数均为整数,无需继续遍历*/
if(nums[k] > 0)
{
break;
}
/*4.遇到重复的负数跳过*/
if((k > 0) && (nums[k] == nums[k - 1]))
{
}
else
{
/*5.分别从头,尾寻找符合要求的数据*/
int i = k + 1;
int j = (int)nums.size() - 1;
int target = 0 - nums[k];
while(i < j)
{
if(target == nums[i] + nums[j])
{
res.push_back({nums[k], nums[i], nums[j]});
/*6.排除相等的数据,防止重复记录*/
while((i < j) && (nums[i] == nums[i + 1]))
{
i ++;
}
while((i < j) && (nums[j] == nums[j - 1]))
{
j --;
}
i++;
j--;
}
else if(target > nums[i] + nums[j])
{
/*7.两数之和小于target,需要更大的数,i往右移动*/
i ++;
}
else
{
/*8.两束之和大于target,需要更小的数,j往左移动*/
j --;
}
}
}
}
return res;
}