给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
解法:排序加双指针,排序的目的是为了方便去除重复的数字以及利用双指针。
class Solution
{
public:
vector<vector<int>> threeSum(vector<int>& nums)
{
vector<vector<int> >ans;
if (nums.size() < 3) return ans;
sort(nums.begin(), nums.end());
int new_size = nums.size() - 2;
for (int i = 0; i < new_size; ++i)
{
if (nums[i] > 0) break;
if (nums[i] == nums[i - 1] && i) continue;//去重
int target = -nums[i];
int top = i + 1, tail = new_size + 1;
while (top < tail)
{
if (nums[top] + nums[tail] == target)
{
ans.push_back({nums[i], nums[top], nums[tail]});
while ((top + 1) < tail && nums[top] == nums[top + 1])++top;//去重
while ((tail - 1) > i && nums[tail] == nums[tail - 1])--tail;//去重
++top;
--tail;
}
else if (nums[top] + nums[tail] > target) --tail;
else top++;
}
}
return ans;
}
};
- 官方题解
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int n = nums.size();
sort(nums.begin(), nums.end());
vector<vector<int>> ans;
// 枚举 a
for (int first = 0; first < n; ++first) {
// 需要和上一次枚举的数不相同
if (first > 0 && nums[first] == nums[first - 1]) {
continue;
}
// c 对应的指针初始指向数组的最右端
int third = n - 1;
int target = -nums[first];
// 枚举 b
for (int second = first + 1; second < n; ++second) {
// 需要和上一次枚举的数不相同
if (second > first + 1 && nums[second] == nums[second - 1]) {
continue;
}
// 需要保证 b 的指针在 c 的指针的左侧
while (second < third && nums[second] + nums[third] > target) {
--third;
}
// 如果指针重合,随着 b 后续的增加
// 就不会有满足 a+b+c=0 并且 b<c 的 c 了,可以退出循环
if (second == third) {
break;
}
if (nums[second] + nums[third] == target) {
ans.push_back({nums[first], nums[second], nums[third]});
}
}
}
return ans;
}
};

来源:力扣(LeetCode)
1985

被折叠的 条评论
为什么被折叠?



