一、题目描述
给你一个包含 n 个整数的数组nums,判断nums中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意: 答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
二、题解
思路:
本题最容易想到的方法是暴力搜索,即通过三层循环将所有可能的情况都列举出来。这种方法不仅时间效率低,而且需要处理重复的三元组,因此需要对其进行优化。
第一次优化:解决重复问题。首先将原数组从小到大排序,再保证枚举的三元组(a,b,c)满足a≤b≤c。在实现时,需要保证在每一重循环中,相邻两次枚举的元素不能相同。
第二次优化:降低时间复杂度。在第二重循环往后枚举元素b’时,有b’>b,则一定有c’<c。也就是说,我们应该从小到大枚举b,同时从大到小枚举c。这样使得第二重循环和第三重循环形成了并列关系。
代码:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
if (nums.size() < 3)
return {};
int size = int(nums.size());
vector<vector<int>> res;
sort(nums.begin(), nums.end());
for (int i = 0; i < size; i++)
{
if (i > 0 && nums[i] == nums[i - 1])
continue;
int k = size - 1;
for (int j = i + 1; j < size; j++)
{
if (j > i + 1 && nums[j] == nums[j - 1])
continue;
int target = -(nums[i] + nums[j]);
while (k > j && nums[k] >= target)
{
if (nums[k] == target)
{
res.push_back({ nums[i],nums[j],nums[k] });
break;
}
k--;
}
}
}
return res;
}
};